小编典典

动态访问pandas数据框列

python

考虑这个简单的例子

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.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) 。

我如何仍保留语法groupby('one').mycol?可以将mycol字符串转换为一些可能工作方式?谢谢!


阅读 196

收藏
2021-01-20

共1个答案

小编典典

您传递一个字符串作为第二个参数。实际上,您正在尝试执行以下操作:

df.'two'

这是无效的语法。如果要动态访问列,则需要使用索引符号,[...]因为点/属性访问器符号不适用于动态访问。


可以进行动态访问。例如,您可以使用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()

2021-01-20