pandas 获取每个事件的第一个和最后一个出现索引

cgvd09ve  于 2023-05-05  发布在  其他
关注(0)|答案(4)|浏览(205)

我有一个pandas.dataframe,其中一列中,等于1的值与重复事件相关。
如何获得每个事件的第一个和最后一个发生索引?
例如,看下面的例子:

import pandas as pd

df = pd.DataFrame({"a": [0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0]})

结果应为:

idxs = [[2,4], [9,12], [17,18]]

非常感谢。

tf7tbtn2

tf7tbtn21#

你可以使用numpy来解决这个问题,使用valueswhereconcatenatediff方法。

import numpy as np
df = pd.DataFrame({"a": [0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0]})
arr = df.values.flatten()
start_indexes = np.where(np.concatenate(([0], np.diff(arr) == 1)))[0]
end_indexes = np.where(np.concatenate((np.diff(arr) == -1, [0])))[0]
print(list(zip(starts, ends))
kninwzqo

kninwzqo2#

首先,我们可以为每组连续数字添加一个列b,其中包含不同的数字

df["b"] = (df["a"]!=df["a"].shift()).cumsum()
a  b
0   0  1
1   0  1
2   1  2
3   1  2
4   1  2
5   0  3
6   0  3
7   0  3
8   0  3
9   1  4
10  1  4
11  1  4
12  1  4
13  0  5
14  0  5
15  0  5
16  0  5
17  1  6
18  1  6
19  0  7

然后我们只考虑1的打击,对于每个组,我们取第一个和最后一个指数

df[df["a"].eq(1)].groupby("b")\
    .apply(lambda x: [x.index.min(), x.index.max()])
b
2      [2, 4]
4     [9, 12]
6    [17, 18]

如果你正在寻找一个列表作为输出,你可以添加.to_list()

df[df["a"].eq(1)].groupby("b")\
    .apply(lambda x: [x.index.min(), x.index.max()])\
    .to_list()
[[2, 4], [9, 12], [17, 18]]
4zcjmb1e

4zcjmb1e3#

创建分组器以划分组

grouper = df['a'].ne(df['a'].shift()).cumsum()

grouper.head()

0    1
1    1
2    2
3    2
4    2

前两个属于组1,接下来的三个连续的1属于组2
然后按分组器分组

g = df.groupby(grouper)['a']
(df[df['a'].eq(1)]
 .groupby(grouper)['a'].agg([pd.Series.first_valid_index, pd.Series.last_valid_index])
 .values.tolist())

输出:

[[2, 4], [9, 12], [17, 18]]
t3irkdon

t3irkdon4#

使用布尔掩码和numpy来整形:

# value is a 1
m = df['a'].eq(1)
# value is either preceded or followed by a non-1
m2 = ~(m.shift(fill_value=False)|m.shift(-1, fill_value=False))

# keep those indices, reshape 2 by 2, convert to list
out = df.index[m&m2].to_numpy().reshape((-1, 2)).tolist()

输出:

[[2, 4], [9, 12], [17, 18]]

相关问题