我有一个Pandas数据帧,包含2列(TrackTRUEPt、EventNumber(和大约50万个条目。我希望保留具有相同TrackTRUEPt值的数据点对,但另外EventNumber的差异为±1,即连续的EventNumber。我不能简单地使用"duplicated"方法,因为在我的数据帧中,通常有两个以上的数据点具有相同的TrackTRUEPt值,所以duplicate保留了所有数据点,而不仅仅是我想要的对。
TrackTRUEPt EventNumber
0 15049.719727 1
1 15049.719727 2
2 5530.503906 3
3 3943.318115 4
4 1760.578979 10
5 1760.578979 11
6 15049.719727 12
7 4931.394043 21
8 4931.394043 22
9 3943.318115 23
10 11068.919922 24
对于这种特殊情况,您将只保留对(第0行,第1行(、(第4行,第5行(和(第7行,第8行(,因为所有这些对都具有相同的TrackTRUEPt值,此外还有连续的事件编号,即
EventNumber(row 1) - EventNumber(row 0) = 2 - 1 = +1,
EventNumber(row 5) - EventNumber(row 4) = 11 - 10 = +1,
EventNumber(row 8) - EventNumber(row 7) = 22 - 21 = +1
预期输出数据帧为
TrackTRUEPt EventNumber
0 15049.719727 1
1 15049.719727 2
4 1760.578979 10
5 1760.578979 11
7 4931.394043 21
8 4931.394043 22
任何帮助都将不胜感激,因为我很难找到最好的方法。
对于计数连续值,通过Series.shift
和Series.cumsum
创建助手Series
,并通过GroupBy.transform
获取计数,同时通过Series.eq
仅比较连续对的2
并通过boolean indexing
:进行过滤
g = df['TrackTRUEPt'].ne(df['TrackTRUEPt'].shift()).cumsum()
df1 = df[g.groupby(g).transform('size').eq(2)].copy()
print (df1)
TrackTRUEPt EventNumber
0 15049.719727 1
1 15049.719727 2
4 1760.578979 10
5 1760.578979 11
7 4931.394043 21
8 4931.394043 22
然后可以用GroupBy.agg
:将最后一个值与第一个值相减
df2 = (df1.groupby('TrackTRUEPt')['EventNumber']
.agg(lambda x: x.iat[-1] - x.iat[0])
.reset_index(name='diff'))
print (df2)
TrackTRUEPt diff
0 1760.578979 1
1 4931.394043 1
2 15049.719727 1
或者因为配对可能使用DataFrame.drop_duplicates
:
a = df1.drop_duplicates('TrackTRUEPt').set_index('TrackTRUEPt')
b = df1.drop_duplicates('TrackTRUEPt', keep='last').set_index('TrackTRUEPt')
df2 = b['EventNumber'].sub(a['EventNumber']).reset_index(name='diff')
print (df2)
TrackTRUEPt diff
0 15049.719727 1
1 1760.578979 1
2 4931.394043 1