簡體   English   中英

熊貓groupby與重疊的組/窗口

[英]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')

首先,我將連接startend數據並命名結果列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)

最后是groupbyapply例如:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM