【问题标题】:Summing over a multiindex pandas DataFrame对多索引 pandas DataFrame 求和
【发布时间】:2017-06-11 20:54:24
【问题描述】:

假设我使用 df.set_index('Class','subclass') 创建了以下数据框,请记住有多个具有子类的类... A>Z。

Class   subclass    
  A       a           
  A       b 
  A       c 
  A       d 
  B       a            
  B       b 

我将如何计算 Class 中的子类并创建一个名为 no of classes 的单独列,以便我可以看到具有最大子类数量的 Class?我在想某种 for 循环,它遍历 Class 字母并计算子类,如果 Class 字母仍然相同。但是,对于这样的问题,这似乎有点违反直觉。是否有更简单的方法,例如 df.groupby[].count?

期望的输出是:

Class   subclass    No. of classes
  A       a                4    
  A       b 
  A       c 
  A       d 
  B       a                2    
  B       b 

我已经尝试了group multi-index pandas dataframe 中显示的级别参数,但这似乎对我不起作用

编辑:

我没有提到我想要返回具有最多子类的类。我通过以下方式实现了这一目标:

df.reset_index().groupby('Class')['subclass'].nunique().idxmax()

【问题讨论】:

  • IIUC 你可以做df['No. of classes'] = df.groupby('Class')['subclass'].transform('count')
  • No. of classes 中需要空值吗?
  • 我希望返回具有最多子类的类。经过更多搜索后,我写了以下内容:'df.reset_index().groupby('Class')['subclass'].nunique().idxmax()' 有效。
  • @Joey - 是的,对于最大数量的子类来说,这是一个很好的解决方案。我再添加一个。

标签: python pandas dataframe multi-index


【解决方案1】:

您可以使用transform,但会得到重复值:

df['No. of classes'] = df.groupby(level='Class')['val'].transform('size')

print (df)
                val  No. of classes
Class subclass                     
A     a           1               4
      b           4               4
      c           5               4
      d           4               4
B     a           1               2
      b           2               2

但如果需要空值:

df['No. of classes'] = df.groupby(level='Class')
                         .apply(lambda x: pd.Series( [len(x)] + [np.nan] * (len(x)-1)))
                         .values
print (df)
                val  No. of classes
Class subclass                     
A     a           1             4.0
      b           4             NaN
      c           5             NaN
      d           4             NaN
B     a           1             2.0
      b           2             NaN

获取最大数量的Class 的另一种解决方案是:

df = df.groupby(level=['Class'])
       .apply(lambda x: x.index.get_level_values('subclass').nunique())
       .idxmax()
print (df)
A

【讨论】:

  • 如果说我想找到每个类中前 3 个 val 的总和并返回总和最高的前 3 个类,我可以使用类似的表达式吗?说 'df.groupby('Class')['val'].nlargest(3)' 对每个 Class 中的前 3 个 val 进行排序,然后应用另一个表达式对前 3 个求和并排序?
  • 你觉得df.groupby('Class')['val'].apply(lambda x: x.nlargest(3).sum()) 吗?
  • 然后如果需要顶部添加idxmax() like df.groupby('Class')['val'].apply(lambda x: x.nlargest(3).sum()).idxmax()
  • 或者如果需要顶部3 再次使用nlargest df.groupby('Class')['val'].apply(lambda x: x.nlargest(3).sum()).nlargest(3)
  • 正是我需要的。非常感谢!
【解决方案2】:

您可以使用 transform 将聚合计算添加回原始 df 作为新列:

In [165]:
df['No. of classes'] = df.groupby('Class')['subclass'].transform('count')
df

Out[165]:
  Class subclass  No. of classes
0     A        a               4
1     A        b               4
2     A        c               4
3     A        d               4
4     B        a               2
5     B        b               2

【讨论】:

    猜你喜欢
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 2022-06-11
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 2018-04-08
    相关资源
    最近更新 更多