创建一个时间序列,如果 D 在开始日期和结束日期之间,则对每天 D 的数据求和
Create a time series that sums data on each day D, if D is between the start date and the end date
我的原始数据是一个包含 三 列的数据框,用于描述旅程:数量、开始日期、结束日期。我的目标是创建一个包含每日索引和 一个 单列的新数据框,该列显示“在每天的方式”,即如果天 > 开始日期和天 < 结束日期,则总数量。
我想我可以通过创建每日索引然后使用 for 循环来实现这一点,该循环每天使用 mask 来过滤数据,然后总和。我还没有设法让它发挥作用,但我认为实际上可能有更好的方法?以下是我对一些虚拟数据的尝试...
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()
您的数据描述了一个阶跃函数,即在 3 月 2 日(午夜)增加了 10,在 3 月 27 日(午夜)减少了 10。
此解决方案使用名为 staircase
的程序包,该程序包基于 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"])
解决方案
创建一个 staircase.Stairs
对象(它是 staircase
,因为 pandas.Series
是 pandas
),它表示阶跃函数。它就像传递开始时间、结束时间和值一样简单,因为您的数据在 pandas.Dataframe
中,可以通过传递列名
来完成
import staircase as sc
sf = sc.Stairs(frame=df, start="startdate", end="enddate", value="quantity")
step函数默认由左闭区间组成。
您可以使用步进函数做很多事情,包括绘图
sf.plot(style="hlines")
如果您只想获取每天开始时的值,那么您可以像这样对阶跃函数进行采样
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
您的问题的更通用的解决方案包括任何日期时间(不仅仅是午夜)的开始和结束时间以及可以使用 slicing and integrating.
实现的任意分箱
我的原始数据是一个包含 三 列的数据框,用于描述旅程:数量、开始日期、结束日期。我的目标是创建一个包含每日索引和 一个 单列的新数据框,该列显示“在每天的方式”,即如果天 > 开始日期和天 < 结束日期,则总数量。 我想我可以通过创建每日索引然后使用 for 循环来实现这一点,该循环每天使用 mask 来过滤数据,然后总和。我还没有设法让它发挥作用,但我认为实际上可能有更好的方法?以下是我对一些虚拟数据的尝试...
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()
您的数据描述了一个阶跃函数,即在 3 月 2 日(午夜)增加了 10,在 3 月 27 日(午夜)减少了 10。
此解决方案使用名为 staircase
的程序包,该程序包基于 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"])
解决方案
创建一个 staircase.Stairs
对象(它是 staircase
,因为 pandas.Series
是 pandas
),它表示阶跃函数。它就像传递开始时间、结束时间和值一样简单,因为您的数据在 pandas.Dataframe
中,可以通过传递列名
import staircase as sc
sf = sc.Stairs(frame=df, start="startdate", end="enddate", value="quantity")
step函数默认由左闭区间组成。 您可以使用步进函数做很多事情,包括绘图
sf.plot(style="hlines")
如果您只想获取每天开始时的值,那么您可以像这样对阶跃函数进行采样
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
您的问题的更通用的解决方案包括任何日期时间(不仅仅是午夜)的开始和结束时间以及可以使用 slicing and integrating.
实现的任意分箱