在 Pandas 中,如何按键中的每 N 行进行分组,保存一列的最后一个值并根据该“集合”中的所有行计算另一列?

Rob*_*ins 2 python pandas

我的数据结构如下,包含时间、类别、活动指示器和数值。

输入

i  time       cat.  active  item_count
0  00:00:00   X     TRUE    2
1  00:00:06   X     FALSE   4
2  00:00:08   X     TRUE    13
3  00:00:25   Y     FALSE   11
4  00:01:10   Y     TRUE    2
5  00:01:58   Y     TRUE    6
6  00:02:53   Y     TRUE    2
7  07:40:29   X     FALSE   1
8  08:34:52   X     FALSE   2
9  11:50:48   X     TRUE    5
10 11:55:42   X     TRUE    3
Run Code Online (Sandbox Code Playgroud)

我想计算类别中每 2 行的活动项目的比率,并复制每个 2 行集中最后一行的时间以获得以下输出:

输出

time     cat.  rate
00:00:06 X     0.33 (2/(2+4))
07:40:29 X     13/14
00:01:10 Y     2/13
00:02:53 Y     8/8
11:50:48 X     5/7
11:55:42 X     3/3
Run Code Online (Sandbox Code Playgroud)

输入中的“集合”将是类别 X 的行 [[0,1], [2,7], [8,9], [10]] 和 [[3,4],[5,6] ] 对于类别 Y。

我该如何设置呢?按类别排序,然后按时间排序,然后逐步遍历每 N 个项目?我在寻找解决方案时发现了 GroupBy.nth,但不确定它是否适用于此处。

jez*_*ael 5

首先使用 创建助手Seriescumcount传递给另一个groupby并使用 聚合 lambda 函数last,最后进行一些数据清理 -reset_index使用rename

另外,对于rate列,只需要对True值求和,然后从右侧除以rdiv所有sum值。

g = df.groupby('cat.').cumcount() // 2
df1 = (df.groupby(['cat.', g], sort=False)
        .agg({'item_count': 'sum', 'time':'last'}))

print (df1)
        item_count      time
cat.                        
X    0           6  00:00:06
     1          14  07:40:29
Y    0          13  00:01:10
     1           8  00:02:53
X    2           7  11:50:48
     3           3  11:55:42

s = df[df['active']].groupby(['cat.', g], sort=False)['item_count'].sum()
print (s)
cat.   
X     0     2
      1    13
Y     0     2
      1     8
X     2     5
      3     3
Name: item_count, dtype: int64
Run Code Online (Sandbox Code Playgroud)
df1['rate'] = df1.pop('item_count').rdiv(s, axis=0)

d= {'time_last':'time'}
df1 = df1.reset_index(level=1, drop=True).reset_index().rename(columns=d)
print (df1)
  cat.      time      rate
0    X  00:00:06  0.333333
1    X  07:40:29  0.928571
2    Y  00:01:10  0.153846
3    Y  00:02:53  1.000000
4    X  11:50:48  0.714286
5    X  11:55:42  1.000000
Run Code Online (Sandbox Code Playgroud)