使用第一次出现的索引计算过渡的最小值和最大值

2024-03-29 12:41:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧:

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

我想计算转换发生了多少次。这里在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})

我还需要获得这些转换的sec列的最小值和最大值。例如,在这里a->b已经发生了3次,其中最小sec值为1,最大sec值为7。我还想知道a->b0的这个转换第一次发生在哪里。对于{{CD12}}列,我考虑转换的第一个值,即^ {CD13}}的索引,并且对于计算,min,max i取过渡的第二个值,即在^ {CD14> }的值。

以下是我想要得到的最终输出:

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

如何在Python中实现这一点

而且我有大量的数据,所以我正在寻找最快的方法


Tags: to数据iddataframedfindexcountcounter
2条回答

从添加以前值为IDsec的列开始:

df['prevID']  = df.ID.shift(fill_value='')
df['prevSec'] = df.sec.shift(fill_value=0)

然后定义以下函数:

def find(df, IDfrom, IDto):
    rows = df.query('prevID == @IDfrom and ID == @IDto')
    tbl = rows.loc[:, ['prevSec', 'sec']].values
    n = rows.index.size
    return (n, tbl.min(), tbl.max()) if n > 0 else (n, 0, 0)

现在,如果您运行此函数,例如查找ab

find(df, 'a', 'b')

您将获得:

(3, 1, 7)

然后为所有其他的值调用此函数

请注意,此函数返回正确的结果,即使没有 给定值之间的转换。当然,你可以选择其他的 如果未发现过渡,minmax的“替代”值

您的转换形式为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()
)

  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

相关问题 更多 >