Ped*_*lho 9 python dataframe pandas pandas-apply
根据我的理解,pandas.DataFrame.apply不会在内部应用更改,我们应该使用其返回对象来保留任何更改.但是,我发现了以下不一致的行为:
让我们应用一个虚函数,以确保原始df保持不变:
>>> def foo(row: pd.Series):
... row['b'] = '42'
>>> df = pd.DataFrame([('a0','b0'),('a1','b1')], columns=['a', 'b'])
>>> df.apply(foo, axis=1)
>>> df
a b
0 a0 b0
1 a1 b1
Run Code Online (Sandbox Code Playgroud)
这表现得如预期.但是,如果我们修改初始化此df的方式,foo将在适用的位置应用更改:
>>> df2 = pd.DataFrame(columns=['a', 'b'])
>>> df2['a'] = ['a0','a1']
>>> df2['b'] = ['b0','b1']
>>> df2.apply(foo, axis=1)
>>> df2
a b
0 a0 42
1 a1 42
Run Code Online (Sandbox Code Playgroud)
我还注意到,如果列dtypes不是'object'类型,则上述情况不正确.为什么apply()在这两个上下文中表现不同?
Python:3.6.5
熊猫:0.23.1
有趣的问题!我相信您所看到的行为是您使用方式的产物apply
。
正如您正确指出的那样,apply
它不旨在用于修改数据框。但是,由于apply
采用任意函数,因此不能保证应用该函数是幂等的并且不会更改数据帧。在这里,您发现了该行为的一个很好的示例,因为您的函数foo
尝试修改它所传递的行apply
。
使用apply
修改行可能会导致这些副作用。这不是最佳实践。
相反,请考虑这种惯用的方法apply
。该函数apply
通常用于创建新列。下面是一个典型使用方式的示例apply
,我相信它会引导您远离这个潜在的麻烦区域:
import pandas as pd
# construct df2 just like you did
df2 = pd.DataFrame(columns=['a', 'b'])
df2['a'] = ['a0','b0']
df2['b'] = ['a1','b1']
df2['b_copy'] = df2.apply(lambda row: row['b'], axis=1) # apply to each row
df2['b_replace'] = df2.apply(lambda row: '42', axis=1)
df2['b_reverse'] = df2['b'].apply(lambda val: val[::-1]) # apply to each value in b column
print(df2)
# output:
# a b b_copy b_replace b_reverse
# 0 a0 a1 a1 42 1a
# 1 b0 b1 b1 42 1b
Run Code Online (Sandbox Code Playgroud)
请注意,pandas 将一行或一个单元格传递给您作为第一个参数提供的函数apply
,然后将函数的输出存储在您选择的列中。
如果您想逐行修改数据框,请查看iterrows
和loc
以获得最惯用的路线。
归档时间: |
|
查看次数: |
1099 次 |
最近记录: |