使用 Pandas GroupBy 找到每个组的一半
Find half of each group with Pandas GroupBy
我需要 select 使用 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')
组的大小分别为 10、7、9,participant_id
13、14、15。我需要的是只占每组的前半部分(或 floor(N/2))。
根据我对 Pandas groupby
的(非常有限的)经验,它应该是这样的:
df.groupby('participant_id')[['summary','participant_id']].apply(lambda x: x[:k_i])
其中 k_i
是每组人数的一半。有没有简单的解决方案来找到 k_i
?
可以按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
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
我需要 select 使用 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')
组的大小分别为 10、7、9,participant_id
13、14、15。我需要的是只占每组的前半部分(或 floor(N/2))。
根据我对 Pandas groupby
的(非常有限的)经验,它应该是这样的:
df.groupby('participant_id')[['summary','participant_id']].apply(lambda x: x[:k_i])
其中 k_i
是每组人数的一半。有没有简单的解决方案来找到 k_i
?
可以按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
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