我有一个如下的数据帧:
Month Col2
A 4
A 5
A 6
A 7
A 8
B 14
B 15
B 16
B 17
B 18
B 19
B 20
B 21
B 22
B 23
我想得到以下:
Month Col2
A 5
A 6
A 7
B 16
B 17
B 18
B 19
B 20
B 21
在上述A组中,顶部1和底部1被去除,因为它们各自是A(5(总数的5%。
在上述B组中,顶部2和底部2被去除,因为它们分别是B总数的5%(10(。
我不知道如何做到这一点。
我认为你的意思可能是,你正在降低每组的顶部和底部10%。
df = pd.DataFrame({'Month': {0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'A', 5: 'B', 6: 'B', 7: 'B', 8: 'B', 9: 'B', 10: 'B', 11: 'B', 12: 'B', 13: 'B', 14: 'B'}, 'Col2': {0: 4, 1: 5, 2: 6, 3: 7, 4: 8, 5: 14, 6: 15, 7: 16, 8: 17, 9: 18, 10: 19, 11: 20, 12: 21, 13: 22, 14: 23}})
pct = .1
for i, g in df.groupby('Month'):
count = g.size
drop = int(pct*count)
# not necessary but helpful to see what's happening, if desired
print(f'dropping top and bottom {pct:0.0%} of {count} obs. for group {i} ({count} obs)')
df.drop(g['Col2'].nlargest(drop).index, inplace=True)
df.drop(g['Col2'].nsmallest(drop).index, inplace=True)
产生
Month Col2
1 A 5
2 A 6
3 A 7
7 B 16
8 B 17
9 B 18
10 B 19
11 B 20
12 B 21
带GroupBy.apply
:
def crop(gr):
gr_len = len(gr)
amt = gr_len // 5
return gr.iloc[amt: -amt]
df.groupby("Month", group_keys=False, sort=False).apply(crop)
其中crop
函数将裁剪量作为组总长度的1/5,并从开始到结束用iloc
切片,
获取
Month Col2
1 A 5
2 A 6
3 A 7
7 B 16
8 B 17
9 B 18
10 B 19
11 B 20
12 B 21
(group_keys
为False
,去掉结果中的分组符Month
的多余索引;sort
为False
,保持分组符列原来的出现顺序。(