【问题标题】:aggregation with indices not present in dataframe数据框中不存在索引的聚合
【发布时间】:2019-07-21 06:40:04
【问题描述】:
df = pd.DataFrame({'x':[1,2,3,4,5,6],'y':[7,8,9,10,11,12],'z':['a','a','a','b','b','b']})
i = pd.Index([0,3,5,10,20])

i 中的索引来自较大的数据帧,df 是该较大数据帧的子集。所以i 中的索引不会出现在df 中。当我这样做时

df.groupby('z').aggregate({'y':lambda x: sum(x.loc[i])}) #I know I can just use .aggregate({'y':sum}), this is just an example to illustrate my problem

我得到这个输出

   y
z    
a NaN
b NaN

以及警告信息

__main__:1: FutureWarning: 
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

如何避免此警告消息并获得正确的输出?在我的示例中,df 的唯一有效索引是 [0,3,5],因此预期的输出是:

   y
z    
a  7 #"sum" of index 0 
b  22 #sum of index [3,5]

编辑

这里的答案很有效,但它们不允许 xy 列的不同类型的聚合。例如,假设我想对x 的所有元素求和,但对于y,只求和索引i 中的元素:

df.groupby('z').aggregate({'x':sum, 'y': lambda x: sum(x.loc[i])})

这是所需的输出:

   y   x                       
z    
a  7   6
b  22  15

【问题讨论】:

  • 预期输出是什么?
  • @jezrael:我已经用预期的输出更新了我的问题
  • 索引 5 不在 i 中。
  • df[df.index.isin(i)].groupby('z')['y'].sum()
  • @ScottBoston:对不起,你是对的。我已经更新了我的问题

标签: python pandas aggregate


【解决方案1】:

编辑更新的问题:

df.groupby('z').agg({'x':'sum','y':lambda r: r.reindex(i).sum()})

输出:

    x   y
z        
a   6   7
b  15  22

使用reindex,仅从 i 中选择那些索引,然后使用dropna 删除所有这些 nan,因为 i 中的索引不在 df 中。然后groupybyagg

df.reindex(i).dropna(how='all').groupby('z').agg({'y':'sum'})

或者,你真的不需要dropna:

df.reindex(i).groupby('z').agg({'y':'sum'})

输出:

      y
z      
a   7.0
b  22.0

【讨论】:

  • 这很好,谢谢,但我真的不明白为什么会这样。 df.reindex(i)10 NaN NaN NaN 添加一行,那么为什么聚合不像我原来的问题那样返回NaN
  • 是的,groupby 不会对 NaN 值组进行分组。但是,您可以使用 dropna 和 how='all' 来删除那些 NaN 记录,如我在第一条语句中所示。
  • 请参阅 SO Post stackoverflow.com/a/18431417/6361531 关于 groupby 中的缺失值。
  • 感谢您的链接。该解决方案效果很好,但不适用于我的问题中已编辑的问题...有解决方法吗?
【解决方案2】:

使用intersectiondf.indexi 只获取匹配的值,然后处理需要的数据:

print (df.loc[df.index.intersection(i)])
   x   y  z
0  1   7  a
3  4  10  b
5  6  12  b

df = df.loc[df.index.intersection(i)].groupby('z').agg({'y':'sum'})
#comment alternative
#df = df.loc[df.index.isin(i)].groupby('z').agg({'y':'sum'})
print (df)
    y
z    
a   7
b  22

编辑:

df1 = df.groupby('z').aggregate({'x':sum, 'y': lambda x: sum(x.loc[x.index.intersection(i)])})
#comment alternative
#df1 = df.groupby('z').aggregate({'x':sum, 'y': lambda x: sum(x.loc[x.index.isin(i)])})
print (df1)
    x   y
z        
a   6   7
b  15  22

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 2013-11-04
    相关资源
    最近更新 更多