[英]Pandas groupby with overlapping groups / windows
我懷疑這種用法與groupby
不兼容,所以也許我實際上是在要求與我想要的模式不同的模式。 我有一個帶有時間跨度的事件的數據框,並希望能夠每天對行進行遍歷/將函數應用於行。 但是,如果一行在一天中開始,另一天結束,那么我希望該行同時包含在這兩行中。
start = pd.DatetimeIndex(start='2018-02-01 21:00:00',
end='2018-02-05, 21:00:00', freq='6h')
df = pd.DataFrame({'start': start.date, 'end': start.shift(1).date, 'value': 1},
columns=['start', 'end', 'value'])
start end value
0 2018-02-01 2018-02-02 1
1 2018-02-02 2018-02-02 1
2 2018-02-02 2018-02-02 1
3 2018-02-02 2018-02-02 1
4 2018-02-02 2018-02-03 1
5 2018-02-03 2018-02-03 1
6 2018-02-03 2018-02-03 1
7 2018-02-03 2018-02-03 1
8 2018-02-03 2018-02-04 1
9 2018-02-04 2018-02-04 1
10 2018-02-04 2018-02-04 1
11 2018-02-04 2018-02-04 1
12 2018-02-04 2018-02-05 1
13 2018-02-05 2018-02-05 1
14 2018-02-05 2018-02-05 1
15 2018-02-05 2018-02-05 1
16 2018-02-05 2018-02-06 1
因此,第一組應包含[0, ..., 4]
,然后包含[4, ..., 8]
等。實際上,事件的間隔不是均勻的,因此每天的長度(以行為單位)不會一定是常數
我所管理的最接近的方法是從groupby.indices
開始,然后操縱組以匹配我想要的內容,但這感覺很groupby.indices
。
{k: np.append(v[0] - 1, v) for k, v in df.groupby('start').indices.items()
if not (len(v) == 1 and v[0] == 0)}
{Timestamp('2018-02-02 00:00:00'): array([0, 1, 2, 3, 4]),
Timestamp('2018-02-03 00:00:00'): array([4, 5, 6, 7, 8]),
Timestamp('2018-02-04 00:00:00'): array([ 8, 9, 10, 11, 12]),
Timestamp('2018-02-05 00:00:00'): array([12, 13, 14, 15, 16])}
相信您要aggregate
。 有很多方法可以去,例如
def e(inp):
return [inp.index]
>>> df.groupby('end').aggregate(e)['start']
end
2018-02-02 [[0, 1, 2, 3]]
2018-02-03 [[4, 5, 6, 7]]
2018-02-04 [[8, 9, 10, 11]]
2018-02-05 [[12, 13, 14, 15]]
2018-02-06 [[16]]
Name: start, dtype: object
和
df.groupby('start').aggregate(e)['end']
start
2018-02-01 [[0]]
2018-02-02 [[1, 2, 3, 4]]
2018-02-03 [[5, 6, 7, 8]]
2018-02-04 [[9, 10, 11, 12]]
2018-02-05 [[13, 14, 15, 16]]
Name: end, dtype: object
現在,您可以玩這些系列游戲,例如,以下內容可以產生輸出
merged = (df.groupby('end').aggregate(e)['start'] + df.groupby('start').aggregate(e)['end']).dropna()
merged.apply(lambda k: k[0].union(k[1]))
2018-02-02 Int64Index([0, 1, 2, 3, 4], dtype='int64')
2018-02-03 Int64Index([4, 5, 6, 7, 8], dtype='int64')
2018-02-04 Int64Index([8, 9, 10, 11, 12], dtype='int64')
2018-02-05 Int64Index([12, 13, 14, 15, 16], dtype='int64')
首先,我將連接start
和end
數據並命名結果列date
例如:
df_concat = pd.DataFrame(pd.concat([df.start,df.end]),columns=['date'])
然后,我將創建一個帶有索引的列:
df_concat['index'] = df_concat.apply(lambda x: x.name,axis=1)
最后是groupby
並apply
例如:
df_concat.groupby('date')['index'].apply(lambda x: sorted(set(x)))
輸出如下:
date
2018-02-01 [0]
2018-02-02 [0, 1, 2, 3, 4]
2018-02-03 [4, 5, 6, 7, 8]
2018-02-04 [8, 9, 10, 11, 12]
2018-02-05 [12, 13, 14, 15, 16]
2018-02-06 [16]
Name: index, dtype: object
就像@RafaelC所說的那樣,有很多方法,這是apply
而不是aggregate
,我不會在相應列表中只刪除一個值的日期
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.