动态访问pandas dataframe列

时间:2017-08-28 14:37:19

标签: python pandas dataframe dynamic accessor

考虑这个简单的例子

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字符串转换为可能以这种方式工作的字符串吗? 谢谢!

2 个答案:

答案 0 :(得分:3)

我认为您需要function myBreakFunc(str, n, x) { var pattern = RegExp(`[^${x}]{${n}}(?=[^${x}])`, 'g'); return str.replace(pattern, '$&' + x) } var res = myBreakFunc("One two three four", 3, ' '); console.log(res);按列名选择列,这是选择列的一般解决方案,因为按属性选择有很多exceptions

  
      
  • 只有当index元素是有效的python标识符时才可以使用此访问权限,例如s.1是不允许的。有关有效标识符的说明,请参见此处。
  •   
  • 如果该属性与现有方法名称冲突,则该属性将不可用,例如: s.min是不允许的。
  •   
  • 同样,如果该属性与以下任何列表冲突,则该属性将不可用:index,major_axis,minor_axis,items,labels。
  •   
  • 在任何这些情况下,标准索引仍然有效,例如: s [' 1'],s [' min']和s [' index']将访问相应的元素或列。
  •   
[]

答案 1 :(得分:3)

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

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()更难以理解。