我有一个由各种组组成的熊猫数据框,例如
df = pd.DataFrame([['A', 2], ['A', 3], ['A', 6], ['B',8], ['B', 2], ['B', 3], ['C', 6], ['C', 2], ['C', 3], ['C', 6]], columns=['Group', 'Val'])
df['count'] = df.groupby('Group')['Group'].transform('count') #get counts per group
Group Val count
0 A 2 3
1 A 3 3
2 A 6 3
3 B 8 3
4 B 2 3
5 B 3 3
6 C 6 4
7 C 2 4
8 C 3 4
9 C 6 4
我想将数据帧分为df_train
和df_test
,其中df_train
包含该组的第一行(按索引)ROUNDUP(0.6 * count)行,而其余行是最后count-ROUNDUP(0.6 * count)行将进入df_test
。也就是说,在我的示例中,对于组A和B,将采用第一行ROUNDUP(0.6 * 3)= 2行,对于组C将采用第一行ROUNDUP(0.6 * 4)= 3行,并将其放入df_train
,然后其他行(这里是每个组的最后一行)在df_test
中。
在大熊猫中做这件事的最好方法是什么?
附加说明:
在我的实际用例中,我已经按日期(在组内)对数据框进行了排序,因此每个组的“最后”行实际上是按日期最新的行,这可能会有所帮助。因此,如果可以的话,我们也可以按日期在组内选择适当的行数...
答案 0 :(得分:1)
按“ Goup”和“ count”分组,每个计数乘以一个常数,并在head()
中指定为整数。
注意:由于math.ceil()不能应用于Pandas.Series,因此我们再次添加了常量以使其四舍五入。这种逻辑并不总是会产生您想要的结果。请验证。
rows = 0.6
gb = df.groupby(['Group','count'])
# Since a rounding-up function cannot be applied to a series
df_train = gb.head(((df['count']*rows)+rows).round().astype(int))
df_train
Group Val count
0 A 2 3
1 A 3 3
3 B 8 3
4 B 2 3
6 C 6 4
7 C 2 4
8 C 3 4
df_test = df[~(df.index.isin(df_train.index))]
df_test
Group Val count
2 A 6 3
5 B 3 3
9 C 6 4