用Pandas GroupBy找出每组的一半

时间:2017-06-27 19:42:59

标签: python pandas pandas-groupby split-apply-combine

我需要使用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

2 个答案:

答案 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