Pandas apply传入lambda表达式引发的问题
在本文中,我们将介绍在使用 Pandas 中 apply 函数传入 lambda 表达式时可能出现的问题及解决方案。
阅读更多:Pandas 教程
什么是 apply 函数?
apply 函数是 Pandas 中常用的一个函数,它的作用是对 DataFrame 中每一行或每一列应用一个指定的函数,然后返回一个新的 DataFrame。该函数的一般语法如下:
DataFrame.apply(func, axis=0, raw=False, result_type=None, args=(), **kwds)
其中,参数含义如下:
– func:要应用的函数,可以是 Lambda 表达式、函数名或任何可以调用的 Python 对象。
– axis:指定按行还是列应用函数,0或’index’代表行(缺省),1或’columns’代表列。
– raw:布尔型,如果设置为True,则传递原始数据而不是 DataFrame;缺省为False。
– result_type:Pandas 的返回类型,取值为’expand’(默认)、’scalar’或’broadcast’。
– args:一般参数元组。
– kwds:关键字参数字典。
如何在 apply 函数中传入 lambda 表达式?
使用 Pandas 的 apply 函数传入 lambda 表达式可以非常方便地对 DataFrame 进行批量处理。以 DataFrame.apply(lambda x: x[‘A’] + x[‘B’], axis=1) 为例,实现对 A、B 两列进行求和的操作。
import pandas as pd
df = pd.DataFrame([[1, 2], [2, 3], [3, 4], [4, 5]], columns=['A', 'B'])
df['C'] = df.apply(lambda x: x['A'] + x['B'], axis=1)
print(df)
输出结果如下:
A B C
0 1 2 3
1 2 3 5
2 3 4 7
3 4 5 9
可以看到,使用 lambda 表达式非常简单方便。然而,有时在 apply 函数中传入 lambda 表达式时,会出现意外问题。
异常问题: lambda 表达式中无法使用 DataFrame 的其他行
在 Pandas 的 apply 函数中,若使用 lambda 表达式的话,我们需要注意不能使用数据集以外的行,否则会报错。
以 DataFrame.apply(lambda x: x[‘A’] + x[‘B’] + df.iloc[0][‘C’], axis=1) 为例:
import pandas as pd
df = pd.DataFrame([[1, 2], [2, 3], [3, 4], [4, 5]], columns=['A', 'B'])
df['C'] = df.apply(lambda x: x['A'] + x['B'] + df.iloc[0]['C'], axis=1)
print(df)
输出结果中发生了异常,显示如下:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-5-679c9c59f546> in <module>
1 df = pd.DataFrame([[1, 2], [2, 3], [3, 4], [4, 5]], columns=['A', 'B'])
----> 2 df['C'] = df.apply(lambda x: x['A'] + x['B'] + df.iloc[0]['C'], axis=1)
3 print(df)
F:\Anaconda3\lib\site-packages\pandas\core\frame.py in __setitem__(self, key, value)
3029 else:
3030 # set column
-> 3031 self._set_item(key, value)
3032
3033 def _setitem_slice(self, key: slice, value):
F:\Anaconda3\lib\site-packages\pandas\core\frame.py in _set_item(self, key, value)
3099 """
3100 self._ensure_valid_index(value)
-> 3101 value = self._sanitize_column(key, value)
3102 NDFrame._ValueError: Columns must be same length as key
错误提示信息显示“列的长度必须与键的长度相同”,即数据集和键必须具有相同的长度。
这是因为在 lambda 表达式中引用了 DataFrame df,df.iloc[0] 此时会引用最开始的 df,而新的 df 加入了新一列的数据,因此列的长度不同。
解决方案
为了避免出现上述的异常问题,我们可以通过引入辅助函数或者 apply 函数中的参数进行解决。
1. 引入辅助函数
我们可以将需要引用的数据单独封装成一个函数,以单独引用该参数。
以 DataFrame.apply(lambda x: x[‘A’] + x[‘B’] + get_c(df), axis=1) 为例:
import pandas as pd
df = pd.DataFrame([[1, 2], [2, 3], [3, 4], [4, 5]], columns=['A', 'B'])
def get_c(df):
return df.iloc[0]['C']
df['C'] = df.apply(lambda x: x['A'] + x['B'] + get_c(df), axis=1)
print(df)
输出结果如下:
A B C
0 1 2 3
1 2 3 6
2 3 4 8
3 4 5 11
可以看到,引入辅助函数之后成功地进行了求和操作。
2. 使用 apply 函数参数
通过使用 apply 函数参数,我们可以替换 x 表达式。
以 DataFrame.apply(lambda x: x[‘A’] + x[‘B’] + df.iloc[0][‘C’], axis=1, result_type=’broadcast’) 为例:
import pandas as pd
df = pd.DataFrame([[1, 2], [2, 3], [3, 4], [4, 5]], columns=['A', 'B'])
df['C'] = df.apply(lambda x, df: x['A'] + x['B'] + df.iloc[0]['C'], axis=1, result_type='broadcast', args=(df,))
print(df)
输出结果如下:
A B C
0 1 2 3
1 2 3 6
2 3 4 8
3 4 5 11
可以看到,通过在 apply 函数中引入列数据集 df,我们成功地进行了求和操作。
总结
在使用 Pandas 的 apply 函数传递 lambda 表达式参数时,不能使用 DataFrame 数据集以外的行,否则会报错。可以通过引入辅助函数或通过 apply 函数参数传递 DataFrame 集合来解决这个问题。
极客笔记