[英]pandas: given a start and end date, add a column for each day in between, then add values?
[英]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 構建在pandas
和numpy
上,用於處理(數學)步進函數。
設置
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.