Pandas apply传入lambda表达式引发的问题

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 集合来解决这个问题。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程