如果我有如下的 DataFrame:
| 信件 | 時間 | |
|---|---|---|
| 0 | X | 2021-01-01 14:00:00 |
| 1 | 是的 | 2021-01-01 18:00:00 |
| 2 | 是的 | 2021-01-03 14:00:00 |
如果時間列(日期時間)中的值在上行時間的 14 小時內,我將如何洗掉一行?
我試過使用:
from datetime import datetime, timedelta
for i, row in enumerate(df):
if i > 0:
if df.at[i, 'Time'] - df.at[i-1, 'Time'] < timedelta(hours=14):
df = df.drop(i)
else:
pass
else:
pass
但我得到與線路相關的 KeyError 1
如果 df.at[i, 'Time'] - df.at[i-1, 'Time'] < timedelta(hours=14):
uj5u.com熱心網友回復:
如果時間戳在較早時間戳的 14 小時內,是否洗掉它取決于是否洗掉較早的時間戳?這個答案考慮了這個問題的答案是“是”的情況。(如果答案是“否”,那么下面測驗資料的結果解決方案將只是第一個時間戳)。
設定
測驗資料:
import pandas as pd
timestamps = pd.Series([0, 6,10,14,16,29,33,45,46]).apply(pd.Timedelta, unit="hours") pd.Timestamp("2022")
timestamps看起來像這樣:
0 2022-01-01 00:00:00
1 2022-01-01 06:00:00
2 2022-01-01 10:00:00
3 2022-01-01 14:00:00
4 2022-01-01 16:00:00
5 2022-01-02 05:00:00
6 2022-01-02 09:00:00
7 2022-01-02 21:00:00
8 2022-01-02 22:00:00
dtype: datetime64[ns]
我們的目標解決方案包括第 1、第 4、第 6 和第 8 個時間戳。
解決方案
該解決方案將使用piso (pandas interval set operations) 包。這個想法是為每個時間戳創建一個 14 小時視窗,即間隔,并迭代地洗掉屬于較早開始的間隔的時間戳。
import piso
# sort timestamps if not already sorted
timestamps = timestamps.sort_values()
# create 14 hour windows for each timestamp. Can be left-closed or right-closed, but not both
intervals = pd.IntervalIndex.from_arrays(timestamps, timestamps pd.Timedelta("14h"))
# create the "disjoint adjacency matrix", which indicates pairwise if intervals are disjoint
mat = piso.adjacency_matrix(intervals, edges="disjoint")
mat將是一個資料框,其索引和列是timestamps. mat.values看起來像這樣
array([[False, False, False, True, True, True, True, True, True],
[False, False, False, False, False, True, True, True, True],
[False, False, False, False, False, True, True, True, True],
[ True, False, False, False, False, True, True, True, True],
[ True, False, False, False, False, False, True, True, True],
[ True, True, True, True, False, False, False, True, True],
[ True, True, True, True, True, False, False, False, False],
[ True, True, True, True, True, True, False, False, False],
[ True, True, True, True, True, True, False, False, False]])
將此矩陣的對角線設定為 True
mat.iloc[range(len(mat)),range(len(mat))] = True
我們將從第一個間隔開始。從第一行mat可以推斷出需要洗掉第二個和第三個間隔。所以我們過濾掉這些區間對應的行和列,然后移動下一個區間(行),以此類推,直到到達最后一行。請注意,我們不需要檢查最后一行的任何交叉點。
i = 0
while i < len(mat) -1:
mat = mat.loc[mat.iloc[i],mat.iloc[i]]
i =1
結果將是一個資料框,其值全部為 True。更重要的是,索引(和列)將是間隔,其左端點是洗掉 14 小時內的時間戳后剩余的時間戳。
即pd.Series(mat.index.left)給
0 2022-01-01 00:00:00
1 2022-01-01 14:00:00
2 2022-01-02 05:00:00
3 2022-01-02 21:00:00
dtype: datetime64[ns]
您可以使用它來過濾原始資料框pandas.Series.isin
uj5u.com熱心網友回復:
您可以使用shift rsub(查找連續時間之間的差異) div(轉換為小時)創建一個布爾掩碼并對其進行過濾:
msk = df['Time'].shift().rsub(df['Time']).div(np.timedelta64(1, 'h')) > 14
out = df[msk]
輸出:
Letter Time
2 y 2021-01-03 14:00:00
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/438193.html
