可以在 pandas apply 方法中使用 lambda 表达式吗?

Posted

技术标签:

【中文标题】可以在 pandas apply 方法中使用 lambda 表达式吗?【英文标题】:Can lambda expressions be used within pandas apply method? 【发布时间】:2018-01-17 12:39:07 【问题描述】:

今天遇到这个lambda表达式,不明白怎么用的:

data["class_size"]["DBN"] = data["class_size"].apply(lambda x: "0:02d1".format(x["CSD"], x["SCHOOL CODE"]), axis=1)

这行代码似乎没有调用 lambda 函数或将任何参数传递给它,所以我很困惑它是如何做任何事情的。这样做的目的是获取两列 CSD 和 SCHOOL CODE,并将每行中的条目组合成一个新行 DBN。那么这个 lambda 表达式会被使用吗?

【问题讨论】:

查看 pandas 文档,apply 将作为参数传入的函数应用到某些东西,这个 lambda 充当将作为参数传入的函数,然后将由apply 函数 发布一个示例 DataFrame 会有所帮助。然后缩小您对该 DataFrame 的困惑。 为什么你用data["class_size"]["DBN"]而不是data["DBN"] 是的。 apply 可以接受 lambda 表达式:pandas.pydata.org/pandas-docs/stable/10min.html#apply Apply 可以接受 lambda 表达式,但您使用的是应用于列而不是整个数据框。请参阅下面的答案。 【参考方案1】:

您将结果错误地写入列。 data["class_size"]["DBN"] 不是选择要写入的列的正确方法。您还选择了要使用 apply 的列,但您希望在整个数据帧中使用它。

data["DBN"] = data.apply(lambda x: "0:02d1".format(x["CSD"], x["SCHOOL CODE"]), axis=1)

【讨论】:

这种方法有两个问题:1)Series.apply() 没有axis 参数。 2) 当我们执行data["class_size"].apply(lambda x: ...) 时,我们无法通过x 访问其他列。解决方案:data.apply(lambda x: "0:02d".format(x["CSD"], x["SCHOOL CODE"]), axis=1)。但可能有更好的矢量化解决方案 Docs for Series.apply() ... @MaxU 你是对的。我已将更改应用于我的代码。我以为他正在申请数据框。【参考方案2】:

pandasSeries 的 apply 方法将函数作为其参数之一。

这是一个简单的例子:

import pandas as pd

data = "numbers":range(30)

def cube(x):
    return x**3

df = pd.DataFrame(data)

df['squares'] = df['numbers'].apply(lambda x: x**2)

df['cubes'] = df['numbers'].apply(cube)

print df

给予:

   numbers  squares  cubes
0        0        0      0
1        1        1      1
2        2        4      8
3        3        9     27
4        4       16     64
...

如您所见,无论是定义一个函数(如 cube)还是使用 lambda 函数都非常有效。

正如已经指出的那样,如果您的特定代码有问题,那是您的 data["class_size"]["DBN"] = ... 不正确。我假设这是一个奇怪的拼写错误,因为您没有提到会导致关键错误。


如果您对此感到困惑,请考虑:

def list_apply(func, mylist):
    newlist = []
    for item in mylist:
        newlist.append(func(item))

这是一个(不是很有效的)函数,用于将函数应用于列表中的每个项目。如果你像以前一样将它与立方体一起使用:

a_list = range(10)

print list_apply(cube, a_list)

你得到:

[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

这是一个简单的例子,说明了 pandas 中的 apply 函数是如何实现的。希望对你有帮助?

【讨论】:

我没有尝试运行这段代码,因为我在阅读另一个项目时发现它,我只是想了解它背后的思考过程和方法。这对理解 apply 函数的工作原理和 lambda 有很大帮助。我认为数据框的方式就像我想的二维数组,所以 ["class_size"] 是我的本地数据集之一,我想添加一列 ["DBN"]。这不是正确的思考方式吗? 数据框是一个二维数组,看起来非常好 - 我不确定“我的数据集之一”是什么意思,但如果你要添加一个列,你希望它是 @987654331 @ 其中xPandas.Series(您通常从数据帧上的单列操作中获得...我没有帮助是吗?)。 我想思考它的方式可能是它像new_variable = operation(old_variable)一样工作,左边的任何东西都是要创建/替换的东西,当前存在的任何东西都应该在@987654335的右边@.【参考方案3】:

您是否使用多索引数据框(即存在列层次结构)?没有看到您的数据很难判断,但我假设是这种情况,因为仅使用 data["class_size"].apply() 会在正常数据帧上产生一个系列(这意味着 lambda 将无法找到您指定的列然后在那里会出错!)

我实际上找到了this answer,它解释了尝试在多索引数据帧中创建列的问题,多索引列创建的一个令人困惑的事情是你可以尝试像你正在做的那样创建一个列,看起来运行没有任何问题,但实际上不会创建你想要的。相反,您需要将data["class_size"]["DBN"] = ... 更改为data["class_size", "DBN"] = ... 所以,完整:

data["class_size","DBN"] = data["class_size"].apply(lambda x: "0:02d1".format(x["CSD"], x["SCHOOL CODE"]), axis=1)

当然,如果它不是多索引数据框,那么这将无济于事,您应该寻找其他答案之一。

【讨论】:

【参考方案4】:

我认为 0:02d 表示“CSD”值的小数点后 2 位。 基本上将 2 个值放在一起形成“DBN”。

【讨论】:

以上是关于可以在 pandas apply 方法中使用 lambda 表达式吗?的主要内容,如果未能解决你的问题,请参考以下文章

pandas数组(pandas Series)-apply方法自定义函数

Python pandas.DataFrame.apply函数方法的使用

使用带有参数的 Pandas groupby() + apply()

使用 apply() 函数在 pandas 中的 groupby 之后创建列表

当在应用中也计算前一个值时,Pandas 中是不是可以使用 dataframe.apply 中的前一行值?

pandas GroupBy上的方法apply:一般性的“拆分-应用-合并”