[英]Keeping track of how many observations fall within a fixed time window when time delta is not constant
我有一個 dataframe 的觀測值按時間索引,但觀測值之間的時間增量不是恆定的。
df
>>>
TimeStamp x1 x2
1 2015-03-01 19:05:01 0.812 18.23
2 2015-03-01 19:22:17 0.121 13.91
3 2015-03-01 19:24:34 0.822 15.10
4 2015-03-01 19:28:53 0.093 22.38
5 2015-03-01 21:49:57 0.291 22.90
6 2015-03-01 23:59:01 0.672 23.12
7 2015-03-02 02:30:01 0.421 28.56
8 2015-03-02 02:30:01 0.591 31.72
9 2015-03-02 02:31:17 0.811 21.71
10 2015-03-02 04:37:19 0.142 16.39
我想計算每個樣本的固定時間 window 內的觀察次數。
如果我的時間 window 是 10 分鍾,那么我想計算 [0, 2, 1, 0, 0, 0, 2, 1, 0] 因為在第一個樣本的 10 分鍾內觀察到 0 個樣本,觀察到 2 個樣本在第二個樣品的 10 分鍾內,在第三個樣品的 10 分鍾內觀察到 1 個樣品,依此類推。可能會同時發生兩個觀察結果,但它們是不同的觀察結果(如 7 和 8)。
如果我的時間 window 是 1 小時,那么我想計算 [3, 2, 1, 0, 0, 0, 2, 1, 0] 因為在第一個樣本的 1 小時內觀察到 3 個樣本,依此類推。
我有一個 function 可以做到這一點,但有兩個問題; 1)它非常慢,因為它逐行迭代數據,並且 2)有時返回的計數是負數,我覺得這很奇怪,因為 timedelta 總是 >= 0。
import pandas as pd
import datetime as dt
def get_count(data: pd.DataFrame, window_hours: int, window_minutes: int) -> np.ndarray:
# we only want to iterate to the sample that is within window_hours + window_minutes from the end
last_sample = data["TimeStamp"].iloc[-1] - dt.timedelta(days=0, hours=window_hours, minutes=window_minutes)
count = np.empty(len(data[data["TimeStamp"] <= last_sample]), dtype=int)
i = 0
for index, row in data[data["TimeStamp"] <= last_day].iterrows():
idx = np.where(data["TimeStamp"] <= (row["TimeStamp"] + dt.timedelta(days=0, hours=window_hours, minutes=window_minutes)))[0][-1]
tmp = idx - index
count[i] = tmp
i += 1
return count
有沒有辦法使用純 pandas / numpy (避免循環)來做到這一點,以便它更快,以及提供所需的 output 我的方法似乎不是?
count()
df = pd.read_csv(io.StringIO(""" TimeStamp x1 x2
1 2015-03-01 19:05:01 0.812 18.23
2 2015-03-01 19:22:17 0.121 13.91
3 2015-03-01 19:24:34 0.822 15.10
4 2015-03-01 19:28:53 0.093 22.38
5 2015-03-01 21:49:57 0.291 22.90
6 2015-03-01 23:59:01 0.672 23.12
7 2015-03-02 02:30:01 0.421 28.56
8 2015-03-02 02:30:01 0.591 31.72
9 2015-03-02 02:31:17 0.811 21.71
10 2015-03-02 04:37:19 0.142 16.39"""), sep="\s\s+", engine="python")
df.TimeStamp = pd.to_datetime(df.TimeStamp)
def within(dfa, **kwargs):
return dfa.TimeStamp.apply(lambda t: dfa.loc[dfa.TimeStamp.gt(t) &
dfa.TimeStamp.le(t+pd.Timedelta(**kwargs)),
"TimeStamp"].count())
df["10min"] = within(df, minutes=10)
df["4hour"] = within(df, hours=4)
時間戳 | x1 | x2 | 10分鍾 | 4小時 | |
---|---|---|---|---|---|
1 | 2015-03-01 19:05:01 | 0.812 | 18.23 | 0 | 4 |
2 | 2015-03-01 19:22:17 | 0.121 | 13.91 | 2 | 3 |
3 | 2015-03-01 19:24:34 | 0.822 | 15.1 | 1 | 2 |
4 | 2015-03-01 19:28:53 | 0.093 | 22.38 | 0 | 1 |
5 | 2015-03-01 21:49:57 | 0.291 | 22.9 | 0 | 1 |
6 | 2015-03-01 23:59:01 | 0.672 | 23.12 | 0 | 3 |
7 | 2015-03-02 02:30:01 | 0.421 | 28.56 | 1 | 2 |
8 | 2015-03-02 02:30:01 | 0.591 | 31.72 | 1 | 2 |
9 | 2015-03-02 02:31:17 | 0.811 | 21.71 | 0 | 1 |
10 | 2015-03-02 04:37:19 | 0.142 | 16.39 | 0 | 0 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.