直观的Pandas教程,介绍如何使用apply()和使用函数applymap()以及如何使用替代值map()
在数据处理中,通常需要对特定的行或列执行操作(例如统计计算,拆分或替换值)以获得新数据。编写一个for循环来遍历Pandas DataFrame和Series可以完成这项工作,但这似乎不是一个好主意。for循环往往具有更多的代码性,更少的代码可读性和较慢的性能。
幸运的是,熊猫已经内置了许多很棒的方法来帮助您实现目标!在本文中,我们将看到如何使用apply()和来执行操作applymap(),以及如何使用来代替值map()。
首先,您应该意识到DataFrame和Series将具有这三种方法中的一些或全部,如下所示:
Pandas官方API参考建议:
- apply()用于沿DataFrame的轴或Series的值应用函数。
- applymap() 用于将功能按元素应用于DataFrame。
- map() 用于将系列中的每个值替换为另一个值。
演示数据集
在深入研究细节之前,让我们首先创建一个DataFrame进行演示。
import pandas as pddf = pd.DataFrame({ 'A': [1,2,3,4], 'B': [10,20,30,40], 'C': [20,40,60,80] }, index=['Row 1', 'Row 2', 'Row 3', 'Row 4'])
如何使用apply()?
Pandas apply()用于沿DataFrame的轴或Series的值应用函数。
让我们从一个简单的示例开始,对每一行求和并将结果保存到新列“ D”中
# Let's call this "custom_sum" as "sum" is a built-in functiondef custom_sum(row): return row.sum()df['D'] = df.apply(custom_sum, axis=1)
这是输出
让我们来看看 df.apply(custom_sum, axis=1)
- 第一个参数custom_sum是一个函数。
- 第二个参数axis是指定将功能应用到哪个轴。0用于将函数应用于每一列,以及1用于将该函数应用于每一行。
让我以一种更直观的方式来解释这个过程。第二个参数axis = 1告诉Pandas使用该行。因此,将custom_sum应用于每行并返回一个新的Series,并将每行的输出作为值。
了解了每一行的总和后,每列的总和只是用来axis = 0代替
df.loc['Row 5'] = df.apply(custom_sum, axis=0)
到目前为止,我们一直在讨论apply()DataFrame。同样,apply()可以在Series的值上使用。例如,将“ C”列乘以2,然后将结果保存到新的“ D”列中
def multiply_by_2(val): return val * 2df['D'] = df['C'].apply(multiply_by_2)
注意,df[‘C’]它用于选择列“ C”,然后apply()使用only参数调用multiply_by_2。因为Series是一维数组,所以我们不再需要指定轴。返回值是一个系列并获得由分配到新列d 。df[‘D’]
将lambda与apply一起使用
您还可以将lambda表达式与Pandas apply()函数一起使用。
等效于lambda的DataFrame每行的总和:
df ['D'] = df.apply(lambda x:x.sum(),axis = 1)
等效于lambda的DataFrame每列的总和:
df ['Row 5'] = df.apply(lambda x:x.sum(),axis = 0)
在系列上乘以2的等效lambda:
df ['D'] = df ['C'].apply(lambda x:x * 2)
使用result_type参数
result_type是apply()设置为'expand','reduce'或'broadcast'获取所需结果类型的参数。
在上述情况下,如果result_type将设置为,'broadcast'则输出将是一个由custom_sum值替换的DataFrame 。
df.apply(custom_sum,axis = 1,result_type ='broadcast')
结果将广播到帧的原始形状,保留原始索引和列。
为了理解result_typeas 'expand'和'reduce',我们首先创建一个返回列表的函数。
def cal_multi_col(row): return [row['A'] * 2, row['B'] * 3]
现在,跨越与数据框架将此功能result_type作为'expand'
def cal_multi_col(row): return [row['A'] * 2, row['B'] * 3]
为了将此附加到现有的DataFrame中,必须将结果保存在变量中,以便可以通过访问列名res.columns。
res = df.apply(cal_multi_col,axis = 1,result_type ='expand')df [ res.columns ] = res
输出为:
接下来,应用功能在整个数据框柱result_type作为'reduce'。result_type='reduce'与相对,'expand'并在可能的情况下返回一个Series,而不是扩展类似列表的结果。
如何使用applymap()?
applymap()仅在DataFrame中可用,并用于整个DataFrame的元素级操作。它已经过优化,在某些情况下比快得多apply(),但是最好apply()在进行任何较重的操作之前将其与进行比较。
例如:输出一个数字为平方的DataFrame
df.applymap(np.square)
map()仅在系列中可用,用于将系列中的每个值替换为另一个值。要了解map()工作原理,我们首先创建一个系列。
>>> s = pd.Series(['cat', 'dog', np.nan, 'rabbit'])>>> s0 cat1 dog2 NaN3 rabbitdtype: object
map()接受一个dict或一个Series。在中找不到的值dict会转换为NaN,除非dict具有默认值(例如defaultdict):
>>> s.map({'cat': 'kitten', 'dog': 'puppy'})0 kitten1 puppy2 NaN3 NaNdtype: object
它还接受一个功能:
>>> s.map('I am a {}'.format)0 I am a cat1 I am a dog2 I am a nan3 I am a rabbitdtype: object
为避免将函数应用于缺失值(并将其保留为NaN),na_action='ignore'可以使用:
>>> s.map('I am a {}'.format, na_action='ignore')0 I am a cat1 I am a dog2 NaN3 I am a rabbitdtype: object
摘要
对于DataFrame:
- apply():当您要沿行或列应用函数时使用。axis = 0用于列和axis = 1行。
- applymap():用于整个DataFrame的元素级操作。
对于系列:
- apply():当您要在Series的值上应用函数时使用。
- map():用于将每个值替换为另一个值。