簡體   English   中英

如果 D 在開始日期和結束日期之間,則創建一個時間序列,對每天 D 的數據求和

[英]Create a time series that sums data on each day D, if D is between the start date and the end date

我的原始數據是 dataframe ,其中包含描述旅程的列:數量開始日期結束日期 我的目標是創建一個新的 dataframe,其中包含一個每日索引和一個單獨的列,該列顯示每天“在路上”的旅程數量的總和,即總數量,如果天 > 開始日期和天 < 結束日期。 我想我可以通過創建每日索引然后使用for循環來實現這一點,該循環每天使用掩碼過濾數據,然后求和。 我還沒有設法讓它工作,但我認為實際上可能有更好的方法? 下面是我對一些虛擬數據的嘗試......

data = [[10, '2020-03-02', '2020-03-27'],
        [18, '2020-03-06', '2020-03-10'],
        [21, '2020-03-20', '2020-05-02'],
        [33, '2020-01-02', '2020-03-01']]
columns = ['quantity', 'startdate', 'enddate']
index = [1,2,3,4]
df = pd.DataFrame(data,index,columns)

index2 = pd.date_range(start='2020-01-01', end='2020-06-01', freq='D')
df2 = pd.DataFrame(0,index2,'quantities')
for t in index2:
    mask = (df['start']<t) & (df['end']>t)
    df2['quantities'] = df[mask]['quantity'].sum()

也許您可以為每條記錄創建日期范圍,然后進行分解和分組:

data = [[10, '2020-03-02', '2020-03-27'],
        [18, '2020-03-06', '2020-03-10'],
        [21, '2020-03-20', '2020-05-02'],
        [33, '2020-01-02', '2020-03-01']]
columns = ['quantity', 'startdate', 'enddate']
index = [1,2,3,4]
df = pd.DataFrame(data,index,columns)

df['range'] = df.apply(lambda x: pd.date_range(x['startdate'],x['enddate'],freq='D'), axis=1)
df = df.explode('range')
df.groupby('range')['quantity'].sum()

您的數據描述了一個步驟 function,即在 3 月 2 日(午夜)它增加了 10 的值,在 3 月 27 日(午夜)它減少了 10。

該解決方案使用稱為staircase的 package 構建在pandasnumpy上,用於處理(數學)步進函數。

設置

data = [[10, '2020-03-02', '2020-03-27'],
        [18, '2020-03-06', '2020-03-10'],
        [21, '2020-03-20', '2020-05-02'],
        [33, '2020-01-02', '2020-03-01']]
columns = ['quantity', 'startdate', 'enddate']
index = [1,2,3,4]
df = pd.DataFrame(data,index,columns)
dates = pd.date_range(start='2020-01-01', end='2020-06-01', freq='D')

df["startdate"] = pd.to_datetime(df["startdate"])
df["enddate"] = pd.to_datetime(df["enddate"])

解決方案

Create a staircase.Stairs object (which is to staircase as pandas.Series is to pandas ) which represents a step function. 就像傳遞開始時間、結束時間和值一樣簡單,因為您的數據位於pandas.Dataframe中,可以通過傳遞列名來完成

import staircase as sc
sf = sc.Stairs(frame=df, start="startdate", end="enddate", value="quantity")

默認情況下,步驟 function 將由左閉區間組成。 階梯函數可以做很多事情,包括繪圖

sf.plot(style="hlines")

在此處輸入圖像描述

如果您只想在每天開始時獲取值,那么您可以像這樣對步驟 function 進行采樣

sf(dates, include_index=True)

結果將是由您的日期范圍索引的pandas.Series

2020-01-01     0
2020-01-02    33
2020-01-03    33
2020-01-04    33
2020-01-05    33
            ..
2020-05-28     0
2020-05-29     0
2020-05-30     0
2020-05-31     0
2020-06-01     0
Freq: D, Length: 153, dtype: int64

您的問題的更通用解決方案包括任何日期時間(不僅僅是午夜)的開始和結束時間以及任意 bin 可以通過slicing 和 integration來實現。

注意:我是樓梯的創造者。 如果您有任何反饋或問題,請隨時與我們聯系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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