我需要使用groupby
选择一半数据框,其中每个组的大小未知,并且可能因组而异。例如:
index summary participant_id
0 130599 17.0 13
1 130601 18.0 13
2 130603 16.0 13
3 130605 15.0 13
4 130607 15.0 13
5 130609 16.0 13
6 130611 17.0 13
7 130613 15.0 13
8 130615 17.0 13
9 130617 17.0 13
10 86789 12.0 14
11 86791 8.0 14
12 86793 21.0 14
13 86795 19.0 14
14 86797 20.0 14
15 86799 9.0 14
16 86801 10.0 14
20 107370 1.0 15
21 107372 2.0 15
22 107374 2.0 15
23 107376 4.0 15
24 107378 4.0 15
25 107380 7.0 15
26 107382 6.0 15
27 107597 NaN 15
28 107384 14.0 15
来自groupyby('participant_id')
的群组的大小分别为participant_id
13,14,15的10,7,9。我需要的是只采取每组的第一半(或地板(N / 2))。
从我(非常有限)的Pandas groupby
体验中,它应该是这样的:
df.groupby('participant_id')[['summary','participant_id']].apply(lambda x: x[:k_i])
其中k_i
是每组大小的一半。是否有一个简单的解决方案来查找k_i
?
答案 0 :(得分:3)
IIUC,您可以在lambda:
中使用大小为// 2的索引切片df.groupby('participant_id').apply(lambda x: x.iloc[:x.participant_id.size//2])
输出:
index summary participant_id
participant_id
13 0 130599 17.0 13
1 130601 18.0 13
2 130603 16.0 13
3 130605 15.0 13
4 130607 15.0 13
14 10 86789 12.0 14
11 86791 8.0 14
12 86793 21.0 14
15 20 107370 1.0 15
21 107372 2.0 15
22 107374 2.0 15
23 107376 4.0 15
答案 1 :(得分:2)
您可以按participant_id
进行分组,并使用transform
方法检查其索引是否在上半部分。这将创建一个布尔系列。然后使用此布尔系列过滤掉原始数据帧。
criteria = df.groupby('participant_id')['participant_id']\
.transform(lambda x: np.arange(len(x)) < int(len(x) / 2))
df[criteria]
index summary participant_id
0 130599 17.0 13
1 130601 18.0 13
2 130603 16.0 13
3 130605 15.0 13
4 130607 15.0 13
10 86789 12.0 14
11 86791 8.0 14
12 86793 21.0 14
20 107370 1.0 15
21 107372 2.0 15
22 107374 2.0 15
23 107376 4.0 15