具有 id 和時間戳的 DF,例如:
id timestamp idx
0 1 2021-10-24 17:56:03.641 0
1 1 2021-10-24 17:56:04.086 1
2 1 2021-10-24 17:56:11.217 2
我正在嘗試將每個 id 中的時間范圍分組 5 分鐘,并將每個組的第一個 idx 設定為整個范圍,如下所示:
id timestamp idx first_index
0 1 2021-10-24 17:56:03.641 0 0
1 1 2021-10-24 17:56:04.086 1 0
2 1 2021-10-24 17:56:11.217 2 0
3 1 2021-10-24 19:33:50.359 3 3 <-- taking new idx out 5 min range
4 1 2021-10-24 19:33:55.278 4 3
我撰寫了以下代碼:
def time_groups(df):
df = df.copy()
# grouping per 5Min and id
g = df.groupby(['id', pd.Grouper(key="timestamp", freq='5min', origin='start')])
# get first values per groups to new column
df['first_index'] = g['idx'].transform('first')
return df
代碼適用于單個 id,但是當我有一些 id 時,它會為同一個 id 產生不同的結果。我撰寫了以下 Colab來重現該問題。
所有資料在 5 分鐘前結束:
id timestamp idx first_index
171 6 2021-10-24 18:03:39.323 171 171
172 6 2021-10-24 18:03:53.551 172 171
173 6 2021-10-24 18:04:21.932 173 171
174 6 2021-10-24 18:04:22.221 174 171
175 6 2021-10-24 18:04:22.484 175 171
176 6 2021-10-24 18:04:36.399 176 171
177 6 2021-10-24 18:04:36.649 177 171
------------------------------------------------- Group end
178 6 2021-10-24 18:06:20.437 178 178
179 6 2021-10-24 18:06:20.695 179 178
180 6 2021-10-24 18:06:21.001 180 178
只有一個 id不會在 5分鐘前結束:
id timestamp idx first_index
171 6 2021-10-24 18:03:39.323 171 171
172 6 2021-10-24 18:03:53.551 172 171
173 6 2021-10-24 18:04:21.932 173 171
174 6 2021-10-24 18:04:22.221 174 171
175 6 2021-10-24 18:04:22.484 175 171
176 6 2021-10-24 18:04:36.399 176 171
177 6 2021-10-24 18:04:36.649 177 171
178 6 2021-10-24 18:06:20.437 178 171
179 6 2021-10-24 18:06:20.695 179 171
180 6 2021-10-24 18:06:21.001 180 171
我錯過了什么?
更新: 如果第一個 ID 被洗掉:
df = df[3:]
代碼作業正常
uj5u.com熱心網友回復:
我認為這是因為 group[er origin 正在查看整個系列中的第一個時間戳,而不是每個分組的 id。
這似乎有效:
def tgs(df):
df_list = [g for _,g in df.groupby('id')]
res_list = []
for df_s in df_list:
g = df_s.groupby([pd.Grouper(key="timestamp", freq='5min', origin='start')])
df_s['first_index'] = g['idx'].transform('first')
res_list.append(df_s)
return pd.concat(res_list)
uj5u.com熱心網友回復:
申請時:
df.groupby(['id', pd.Grouper(key="timestamp", freq='5min', origin='start')])
分組的origin是timestamp整個資料幀中的第一個時間戳,而不是每個組。
根據檔案‘start’: origin is the first value of the timeseries https://pandas.pydata.org/docs/reference/api/pandas.Grouper.html
看著df.groupby(['id', pd.Grouper(key="timestamp", freq='5min', origin='start')]).size()你可以看到所有組都在 5 分鐘間隔內(或 5 分鐘間隔的乘法),即使是不同的組id:
id timestamp
1 2021-10-24 17:56:03.641 3
2 2021-10-24 19:31:03.641 10
2021-10-24 19:36:03.641 9
...
6 2021-10-24 18:01:03.641 7
2021-10-24 18:06:03.641 13
...
如果你看id6,它的第一組實際上比它的第一個事件更早。這是出于相同的原因 - 所有用戶的“桶”都基于從整個資料集的第一個時間戳開始的 5 分鐘間隔。之前的所有行都18:06:03.641分組在一個18:01:03.641“桶”中,之后的所有行都分組到18:06:03.641“桶”中。
資料集的第一行是最早的,因此當您洗掉第一個用戶時,該錯誤不再可見。
id我認為您可以通過首先分組,然后使用 apply 應用額外的 group-with-grouper 來獲得您正在尋找的功能:
def split_to_five_minute_groups(x):
return (x.groupby([pd.Grouper(key="timestamp", freq='5min', origin='start')]))[['idx']].transform('first')
df['first_idx'] = df.groupby(['id']).apply(split_to_five_minute_groups)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/414802.html
標籤:
上一篇:計算熊貓資料框中定義組中的元素
