掘金 后端 ( ) • 2024-04-15 15:22

当许多人开始踏足数据分析领域时,他们常常会对选择何种工具感到迷茫。在这个充满各种选项的时代,为什么会有这么多人选择 Pandas 作为他们的数据分析工具呢?这个问题似乎简单,但背后涉及了许多关键因素。在探究这个问题之前,让我们先理解一下 Pandas 的背景和特点。

优化的数据结构: Pandas提供了几种高效的数据结构,如DataFrame和Series,它们是为了优化数值计算和数据操作而设计的。这些数据结构在内存中以连续块的方式存储数据,有助于提高数据访问速度。

DataFrame的一列就是Series,Series可以转化为DataFrame,调用方法函数to_frame()即可

Series 是 pandas 中的一种数据结构,可以看作是带有标签的一维数组。它由两部分组成:索引(Index)值(Values)

  • 索引(Index): 索引是用于标识每个元素的标签,可以是整数、字符串、日期等类型的数据。索引提供了对 Series 中数据的标签化访问方式。
  • 值(Values): 值是 Series 中存储的实际数据,可以是任何数据类型,如整数、浮点数、字符串等。

底层使用C语言: Pandas的许多内部操作都是用Cython或C语言编写的,Cython是一种Python的超集,它允许将Python代码转换为C语言代码,从而提高执行效率。

向量化操作: Pandas支持向量化操作,这意味着可以对整个数据集执行单个操作,而不是逐行或逐列地进行迭代。向量化操作通常比纯Python循环更快,因为它们可以利用底层的优化和硬件加速。

利用内置函数: Pandas广泛使用内置函数来执行常见的数据处理任务,如排序、分组和聚合。这些函数通常经过高度优化,能够快速处理大量数据。

了解完这些,接下来,让我们一起探索 Pandas 中那些不可或缺的常用函数,掌握数据分析的关键技能。

①.map() 函数

用于根据传入的字典或函数,对 Series 中的每个元素进行映射或转换。

具体来说,map() 函数可以接受一个字典或一个函数作为参数,然后根据这个字典或函数对 Series 中的每个元素进行映射或转换,生成一个新的 Series,并返回该 Series。

如果传入的是一个字典,则 map() 函数将会使用字典中键对应的值来替换 Series 中的元素。如果传入的是一个函数,则 map() 函数将会使用该函数对 Series 中的每个元素进行转换。

举个例子

import pandas as pd

# 创建一个 Series
s = pd.Series(['apple', 'banana', 'cherry'])

# 定义一个字典,用于替换元素
replacement_dict = {'apple': 'red', 'banana': 'yellow', 'cherry': 'red'}

# 使用 map() 函数根据字典替换元素
s_mapped = s.map(replacement_dict)

print(s_mapped)

运行结果

0      red
1   yellow
2      red
dtype: object

②.fillna()函数

fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)

参数:

  • value:用于填充的空值的值。
  • method: {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, 默认为 None。定义了填充空值的方法, pad / ffill表示用前面行/列的值,填充当前行/列的空值; backfill / bfill表示用后面行/列的值,填充当前行/列的空值。
  • axis:轴。0或’index’,表示按行删除;1或’columns’,表示按列删除。
  • inplace:是否原地替换。布尔值,默认为False。如果为True,则在原DataFrame上进行操作,返回值为None。
  • limit:int, default None。如果method被指定,对于连续的空值,这段连续区域,最多填充前 limit 个空值(如果存在多段连续区域,每段最多填充前 limit 个空值)。如果method未被指定, 在该axis下,最多填充前 limit 个空值(不论空值连续区间是否间断)
  • downcast:dict, default is None,字典中的项为,为类型向下转换规则。或者为字符串“infer”,此时会在合适的等价类型之间进行向下转换,比如float64 to int64 if possible。

举个例子一 传入字典

import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({'A': [1, 2, None, 4],
                   'B': ['a', 'b', None, 'd']})

# 使用 fillna() 方法填充缺失值,指定不同的填充值
filled_df = df.fillna({'A': 0, 'B': '填充值'})

print("填充指定值的结果:")
print(filled_df)

运行结果

填充指定值的结果:
     A    B
0  1.0    a
1  2.0    b
2  0.0  填充值
3  4.0    d

例子二 传入值

import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({'A': [1, 2, None, 4],
                   'B': ['a', 'b', None, 'd']})


# 使用 fillna() 方法填充缺失值,不指定填充值,默认使用 NaN
default_filled_df = df.fillna("test")

运行结果

      A     B
0     1     a
1     2     b
2  test  test
3     4     d

③.extend() 函数,将一个可迭代对象的所有元素添加到列表的末尾。

举个例子

# 创建一个列表
list1 = [1, 2, 3]

# 创建另一个列表
list2 = [4, 5, 6]

# 使用 extend() 方法将 list2 扩展到 list1
list1.extend(list2)

print(list1)  # 输出: [1, 2, 3, 4, 5, 6]


# 创建一个列表
list1 = [1, 2, 3]

# 创建一个字典
dict1 = {'a': 10, 'b': 20, 'c': 30}

# 使用 extend() 方法将 dict1 的键扩展到 list1
list1.extend(dict1)

print(list1)  # 输出: [1, 2, 3, 'a', 'b', 'c']

④.df.index.difference(null_ind) 查找两个索引的集合差异

举个例子

import pandas as pd

# 创建两个索引对象
index1 = pd.Index([1, 2, 3, 4])
index2 = pd.Index([3, 4, 5, 6])

# 使用 difference() 方法获取两个索引对象之间的差异
index_difference = index1.difference(index2)

print("两个索引对象之间的差异:")
print(index_difference)

运行结果

两个索引对象之间的差异:
Int64Index([1, 2], dtype='int64')

⑤.astype() 方法用于将 Series 的数据类型转换为指定的数据类型

举个例子

import pandas as pd

# 创建一个 Series
s = pd.Series([1, 2, 3, 4])

# 使用 astype() 方法将 Series 的数据类型转换为字符串类型
s_str = s.astype(str)

print("转换数据类型后的 Series:")
print(s_str)

运行结果

转换数据类型后的 Series:
0    1
1    2
2    3
3    4
dtype: object

⑥.pd.cut()函数

将连续性数值进行离散化处理:如对年龄、消费金额等进行分组 pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise', ordered=True)

重点说下 bins :整数,标量序列或者间隔索引,是进行分组的依据,

  • 如果填入整数n,则表示将x中的数值分成等宽的n份(即每一组内的最大值与最小值之差约相等);
  • 如果是标量序列,序列中的数值表示用来分档的分界值
  • 如果是间隔索引,“ bins”的间隔索引必须不重叠

举个例子

import pandas as pd

# 创建一个 Series
s = pd.Series([10, 20, 30, 40, 50])

# 使用 pd.cut() 函数将数据划分为三个区间
bins = [0, 30, 40, 100]  # 区间边界
labels = ['低', '中', '高']  # 区间标签
categories = pd.cut(s, bins=bins, labels=labels)

print("划分区间后的结果:")
print(categories)

运行结果

划分区间后的结果:
0    低
1    低
2    低
3    中
4    高
dtype: category
Categories (3, object): ['低' < '中' < '高']
import pandas as pd
 
# 创建一个简单的DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [5, 4, 3, 2, 1]
})
 
# 查找列'A'中大于3的所有行,并将结果转换为64位整数
result = (df['A'] > 3).astype('int64')
 
print(result)

-- 打印结果

0    0
1    0
2    0
3    1
4    1
dtype: int64

⑦.pd.merge()

pd.merge(left, right, how = 'inner', on = None, left_on = None, right_on = None,
         left_index = False, right_index = False, sort = True, suffixes = ('_x','_y'),
         copy = True, indicator = False, validate = None)

参数

  • left、right:需要连接的两个DataFrame或Series,一左一右
  • how:两个数据连接方式,默认为inner,可设置inner、outer、left或right
  • on:作为连接键的字段,左右数据中都必须存在,否则需要用left_on和right_on来指定
  • left_on:左表的连接键字段
  • right_on:右表的连接键字段
  • left_index:为True时将左表的索引作为连接键,默认为False
  • right_index:为True时将右表的索引作为连接键,默认为False
  • suffixes:如果左右数据出现重复列,新数据表头会用此后缀进行区分,默认为_x和_y

举个例子

import pandas as pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [1, 2, 3], 'C': [7, 8, 9]})

# 使用 pd.merge() 函数根据 'A' 列合并两个 DataFrame
merged_df = pd.merge(df1, df2, on='A')

print("合并后的 DataFrame:")
print(merged_df)

运行结果

合并后的 DataFrame:
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

在本文中,我们深入探讨了Pandas库中一系列高效的数据处理方法。这些方法不仅极大地简化了数据处理的复杂性,而且提供了强大的功能集,使得数据分析工作更为高效和灵活。我们从基础的Series和DataFrame结构出发,逐步深入到数据的清洗、转换和处理技巧,掌握了一套能够应对多样化数据分析任务的工具箱。尽管本文仅触及了Pandas强大功能的表面,但其广阔的应用领域和深邃的技术内涵仍待我们进一步挖掘和学习。