我有一个pandas数据帧,它看起来是这样的:
import pandas as pd
dt = pd.DataFrame({'idx':[1,2,3,4,5,1,2,3,4,5], 'id':[1,1,1,1,1,2,2,2,2,2], 'value':[5,10,15,20,25, 55,65,75,85,97]})
我还有一个是这样的:
dt_idx = pd.DataFrame({'cutoff':[1,1,1,3,3,3,3,3,5,5,5,5,2,2,2,2,2,2,2,4,4]})
对于DT_IDX
中的3个“最常见”cutoff
s(在本玩具示例中是3,5和2),我希望获得dt
数据帧的mean
和value
列的std
,用于以下两组:
idx<=截止
和idx>; 截止
有没有一种蟒蛇式的方法来做这件事?
这里的一个简单循环是一个很好的选择。 使用value_counts
获取您关心的截止值,然后循环遍历这些截止值。 您可以使用groupby
同时获取<=
和>
。 将所有内容存储在一个dict中,以截止值为键,然后您可以concat
来获得一个带有多索引的数据帧。
d = {}
for cutoff in dt_idx.cutoff.value_counts().head(3).index:
d[cutoff] = dt.groupby(dt.idx.gt(cutoff))['value'].agg(['mean', 'std'])
pd.concat(d, names=['cutoff', 'greater_than_cutoff'])
mean std
cutoff greater_than_cutoff
2 False 33.750000 30.652624
True 52.833333 36.771819
3 False 37.500000 30.943497
True 56.750000 39.903007
5 False 45.200000 34.080949
首先,我们得到3个最常用的值,然后对每个值使用groupby.agg
。
import numpy as np
n=3
l = dt_idx['cutoff'].value_counts()[:n].index
new_df = pd.concat({val : dt.groupby(np.where(dt['idx'].le(val),
'less than or equal',
'higher'))['value']
.agg(['mean','std'])
for val in l}, axis=1)
print(new_df)
2 3 5
mean std mean std mean std
higher 52.833333 36.771819 56.75 39.903007 NaN NaN
less than or equal 33.750000 30.652624 37.50 30.943497 45.2 34.080949
#new_df.stack(0).swaplevel().sort_index()
# mean std
#2 higher 52.833333 36.771819
# less than or equal 33.750000 30.652624
#3 higher 56.750000 39.903007
# less than or equal 37.500000 30.943497
#5 less than or equal 45.200000 34.080949