使用熊猫中首次出现的索引计算过渡的最小值和最大值

San*_*apa 10 python numpy pandas

我有一个数据框:

df = pd.DataFrame({'ID':['a','b','d','d','a','b','c','b','d','a','b','a'], 
                   'sec':[3,6,2,0,4,7,10,19,40,3,1,2]})
print(df)
   ID  sec
0   a    3
1   b    6
2   d    2
3   d    0
4   a    4
5   b    7
6   c   10
7   b   19
8   d   40
9   a    3
10  b    1
11  a    2
Run Code Online (Sandbox Code Playgroud)

我想计算发生了多少次转换。此处在ID列中a->b被视为过渡,对于b->d, d->d, d->a, b->c, c->b, b->a. 我可以使用以下方法执行此操作Counter

Counter(zip(df['ID'].to_list(),df['ID'].to_list()[1:]))
Counter({('a', 'b'): 3,
         ('b', 'd'): 2,
         ('d', 'd'): 1,
         ('d', 'a'): 2,
         ('b', 'c'): 1,
         ('c', 'b'): 1,
         ('b', 'a'): 1})
Run Code Online (Sandbox Code Playgroud)

我还需要获得sec这些转换列的最小值和最大值。例如,这里a->b发生了 3 次,其中 min secvalue is1和 max secvalue is 7。此外,我想获得此转换首次发生的位置为a->b0。对于该transition_index列,我考虑转换的第一个值,即a计算的索引,min,max 我取转换的第二个值,即值 at b

这是我想要获得的最终输出:

df = pd.DataFrame({'ID_1':['a','b','d','d','b','c','b'], 
                   'ID_2':['b','d','d','a','c','b','a'],
                   'sec_min':[1,2,0,3,10,19,2],
                   'sec_max':[7,40,0,4,10,19,2],
                   'transition_index':[0,1,2,3,5,6,10],
                   'count':[3,2,1,2,1,1,1]})
print(df)
  ID_1 ID_2  sec_min  sec_max  transition_index  count
0    a    b        1        7                 0      3
1    b    d        2       40                 1      2
2    d    d        0        0                 2      1
3    d    a        3        4                 3      2
4    b    c       10       10                 5      1
5    c    b       19       19                 6      1
6    b    a        2        2                10      1
Run Code Online (Sandbox Code Playgroud)

我怎样才能在 Python 中实现这一点?

另外我有大量的数据,所以我正在寻找最快的方法。

ALo*_*llz 10

你有形式的过渡from -> to'transition_index'基于“from”行的索引,而'sec'聚合基于与“to”行关联的值。

我们可以移动 ID 上的索引和组以及移动的 ID,允许我们使用具有命名聚合的单个 groupby 来获得所需的输出。


df = df.reset_index()
df['index'] = df['index'].shift().astype('Int64')

(df.groupby([df['ID'].shift(1).rename('ID_1'), df['ID'].rename('ID_2')], sort=False)
   .agg(sec_min=('sec', 'min'),
        sec_max=('sec', 'max'),
        transition_index=('index', 'first'),
        count=('sec', 'size'))
   .reset_index()
)
Run Code Online (Sandbox Code Playgroud)
  ID_1 ID_2  sec_min  sec_max  transition_index  count
0    a    b        1        7                 0      3
1    b    d        2       40                 1      2
2    d    d        0        0                 2      1
3    d    a        3        4                 3      2
4    b    c       10       10                 5      1
5    c    b       19       19                 6      1
6    b    a        2        2                10      1
Run Code Online (Sandbox Code Playgroud)