我遇到一种情况,我想根据合同的开始日期,结束日期和总支出来计算每日支出。下一步是按月汇总每日支出金额。这很容易,我将在稍后展示。但是,还有另一个日期(inv date
);如果start
在inv date
之前,则应将inv date
之前的所有每日金额相加并计入与inv date
相同的期间。
首先,容易的部分。
df = pd.DataFrame({'start': ['1/1/2018'],
'end': ['3/15/2018'],
'inv date': ['2/1/2018'],
'spend': [400]})
start end inv date spend
0 1/1/2018 3/15/2018 2/1/2018 400
创建合同的日期范围
prd = pd.period_range(df.loc[0, 'start'], df.loc[0, 'end'], freq='D')
prd = pd.Series(1, prd) # empty series to get the number of days in the monthly period
prd = prd.resample('M').size() * (df.loc[0, 'spend'] / prd.resample('M').size().sum())
这给了我以下系列:根据月中天数分配的每月总支出...到目前为止,还算不错。
prd
2018-01 167.567568
2018-02 151.351351
2018-03 81.081081
Freq: M, dtype: float64
困难的部分(对我而言)
如上所述,基于
inv date
,该系列实际上应如下所示:2018-01 0
2018-02 318.918919
2018-03 81.081081
Freq: M, dtype: float64
因为
inv date
是在start
日期之后,所以我不想在inv date
之后添加它。仅供参考:318 = 167 + 151(即上述2/2018中的总数)。resample
可以吗?如果没有,最有效的方法是什么? 最佳答案
从“简单部分”部分的结尾开始,以df
和prd
开头:
# Get the inv date as a pandas Timestamp
invdate = pd.to_datetime(df['inv date'])[0]
oneday = pd.offsets.Day(1)
# Pandas slicing includes BOTH endpoints, so we need this one-day
# offset to get all values strictly before the inv date
prd.loc[invdate] = prd[invdate] + prd[:invdate - oneday].sum()
prd.loc[:invdate - oneday] = 0
# output
2018-01 0.000000
2018-02 318.918919
2018-03 81.081081
Freq: M, dtype: float64
关于python - 有条件的重采样- Pandas ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48453212/