pandas 为什么lambda可以作用于在Python中使用panda.dataframe.assign生成的新列?

bhmjp9jg  于 2023-02-17  发布在  Python
关注(0)|答案(2)|浏览(137)

我经常使用panda.DataFrame.assign()来实现Python中的方法链。
当使用现有列计算值时,我从来不需要使用lambda。但是如果我想使用我在同一个assign语句中创建的列创建一个计算列,我必须使用lambda x。所以下面的代码可以工作,但是我不明白为什么lambda在下面的代码中工作。
假设我有一个已有的Dataframe,其中包含A、B、C列。使用assign语句,我想通过将A和B相乘来改变A。我还想通过将B和C相乘来创建一个新列D。然后我想将C和D相乘(这只适用于lambda,为什么lambda会记住我创建了列D,而普通的df['D'] * df ['C']不会呢?
| A类|B|C级|
| - ------|- ------|- ------|
| 一个|两个|三个|

df = (df
      .assign(A = df['A'] * df['B'],
              D = df['B'] * df['C'],
              D = lambda x: x['D'] * x['C']))
nwwlzxa7

nwwlzxa71#

因为参数是在调用函数之前计算的,所以在D列被添加到 Dataframe 之前,你不能在参数列表中引用x['D']
但是当你使用lambda的时候,x['D']的求值会被延迟到df.assign()调用它的时候,它是在处理了D = df['B'] * df['C']参数之后才调用的,D = df['B'] * df['C']参数创建了D列,所以它可以引用那个列。

c7rzv4ha

c7rzv4ha2#

可以在同一个赋值中赋值多个列。'**kwargs'中后面的项可能指'df'中新创建或修改的列;按顺序计算项并将其分配到"df"中。
首先,它与执行的顺序有关。
使用.assign(A = df['A'] * df['B']时,在执行df.assign之前计算df['A']

df = pd.DataFrame({"A": [1], "B": [2], "C": [3]})
assign = df.assign

def debug_assign(**kwargs):
    print("Hello from: assign()")
    print(datetime.now())
    assign(**kwargs)

df.assign = debug_assign
>>> df.assign(D = new_value())
Hello from: new_value()
2023-02-14 16:08:38.424683
Hello from: assign()
2023-02-14 16:08:38.424722

至于lambda--它就像一个"迷你函数",当你声明一个lambda时,就像定义一个函数一样,实际上什么都不执行。

>>> lambda x: x['D'] * x['C']
<function __main__.<lambda>(x)>

含义:

>>> df.assign(D = lambda x: x['D'] * x['C'])

类似于:

>>> def callback(): return x['D'] * x['C']
>>> df.assign(D = callback)

函数可以赋给变量并作为参数传递。

>>> my_other_print = print
>>> my_other_print
<function print>

在使用()之前不会执行/调用它们-(注意D = callback中没有()

>>> my_other_print("hello")
hello

pandas检查某个东西是否是"可调用的"--如果是,它将针对当前的"状态"运行,也就是说,包含所有之前计算过的赋值参数。

相关问题