考虑这个简单的例子
import pandas as pd df = pd.DataFrame({'one' : [1,2,3], 'two' : [1,0,0]}) df Out[9]: one two 0 1 1 1 2 0 2 3 0
我想编写一个以数据框df和列为输入的函数mycol。
df
mycol
现在这有效:
df.groupby('one').two.sum() Out[10]: one 1 1 2 0 3 0 Name: two, dtype: int64
这也适用:
def okidoki(df,mycol): return df.groupby('one')[mycol].sum() okidoki(df, 'two') Out[11]: one 1 1 2 0 3 0 Name: two, dtype: int64
但这 失败了
def megabug(df,mycol): return df.groupby('one').mycol.sum() megabug(df, 'two') AttributeError: 'DataFrameGroupBy' object has no attribute 'mycol'
怎么了
我担心okidoki使用某些 链接 可能会产生一些细微的错误(https://pandas.pydata.org/pandas- docs/stable/indexing.html#why-does-assignment-fail-when-using-chained- indexing) 。
okidoki
我如何仍保留语法groupby('one').mycol?可以将mycol字符串转换为一些可能工作方式?谢谢!
groupby('one').mycol
您传递一个字符串作为第二个参数。实际上,您正在尝试执行以下操作:
df.'two'
这是无效的语法。如果要动态访问列,则需要使用索引符号,[...]因为点/属性访问器符号不适用于动态访问。
[...]
可以进行动态访问。例如,您可以使用getattr(但我 不 建议这样 做 ,这是一种反模式):
getattr
In [674]: df Out[674]: one two 0 1 1 1 2 0 2 3 0 In [675]: getattr(df, 'one') Out[675]: 0 1 1 2 2 3 Name: one, dtype: int64
可以从groupby调用中动态选择按属性,例如:
In [677]: getattr(df.groupby('one'), mycol).sum() Out[677]: one 1 1 2 0 3 0 Name: two, dtype: int64
但是 不 要这样做。这是一种可怕的反模式,比更加难以理解df.groupby('one')[mycol].sum()。
df.groupby('one')[mycol].sum()