Python 数据帧中不存在索引的聚合
Python 数据帧中不存在索引的聚合,python,pandas,aggregate,Python,Pandas,Aggregate,i中的索引来自较大的数据帧,df是该较大数据帧的子集。因此,在i中会有索引,而在df中不会有索引。当我这样做的时候 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]) 我得到这个输出 df.groupby('z').aggregate({'y':lambda x: sum(x.loc[i])}) #I know
i
中的索引来自较大的数据帧,df
是该较大数据帧的子集。因此,在i
中会有索引,而在df
中不会有索引。当我这样做的时候
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])
我得到这个输出
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
如何避免此警告消息并获得正确的输出?在我的示例中,df
的唯一有效索引是[0,3,5]
,因此预期输出为:
__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.
编辑
这里的答案非常有效,但它们不允许对x
和y
列进行不同类型的聚合。例如,假设我想对x
的所有元素求和,但对于y
只对索引I
中的元素求和:
y
z
a 7 #"sum" of index 0
b 22 #sum of index [3,5]
这是所需的输出:
df.groupby('z').aggregate({'x':sum, 'y': lambda x: sum(x.loc[i])})
编辑更新的问题:
输出:
df.groupby('z').agg({'x':'sum','y':lambda r: r.reindex(i).sum()})
df.reindex(i).groupby('z').agg({'y':'sum'})
使用reindex
,仅从i中选择那些索引,然后使用dropna
从中删除所有那些NAN,因为i中的索引不在df中。然后groupby
和agg
:
x y
z
a 6 7
b 15 22
或者,你真的不需要放弃NA:
df.reindex(i).dropna(how='all').groupby('z').agg({'y':'sum'})
输出:
df.groupby('z').agg({'x':'sum','y':lambda r: r.reindex(i).sum()})
df.reindex(i).groupby('z').agg({'y':'sum'})
使用df.index
和i
仅获取匹配值,然后处理数据,如需要:
y
z
a 7.0
b 22.0
编辑:
什么是预期的输出?@jezrael:我已经用预期的输出更新了我的问题。索引5不在I.
df[df.index.isin(I)]。groupby('z')['y'].sum()
@ScottBoston:对不起,你是对的。我已经更新了我的问题这很好,谢谢,但我真的不明白为什么会这样df.reindex(i)
添加了一行10 NaN
,那么为什么聚合没有像我原来的问题那样返回NaN
?是的,groupby不按NaN值组分组。但是,您可以使用dropna和how='all'删除那些NaN记录,正如我在第一条语句中所示。请参阅关于groupby中缺少值的文章。谢谢您的链接。这个解决方案效果很好,但它不适用于我问题中编辑的问题。。。有解决办法吗?
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