我在 python 中有一个函数,用于在上采样时分配值。例如,要对我的汽车从每月到每天的行驶距离进行上采样:
def distribute(df, freq:str):
# if there's an easier way please do comment
df_new = df.resample(freq).asfreq().fillna(0)
return df_new.groupby(pd.Grouper(freq=df.index.freq)).transform(np.mean)
import pandas as pd
import numpy as np
distances = pd.Series([300, 300], pd.period_range('2020-02', freq='M', periods=2))
distribute(distances, 'D')
2020-02-01 10.344828
2020-02-02 10.344828
2020-02-03 10.344828
2020-02-04 10.344828
... ...
2020-03-28 9.677419
2020-03-29 9.677419
2020-03-30 9.677419
2020-03-31 9.677419
Freq: D, dtype: float64
该函数将每个月的值平均除以该月的天数,这会导致该2020-02
值除以 29,2020-03
在这种情况下,根据需要将该值除以 31。
但是,当上采样到周期具有不均匀持续时间的频率时,这会给我带来不想要的结果。此属性的两种情况:
- 逐月:
distances2 = pd.Series([366], pd.PeriodIndex(['2020'], freq='Y'))
distribute(distances2, 'M')
2020-01 30.5
2020-02 30.5
... ...
2020-11 30.5
2020-12 30.5
Freq: M, dtype: float64
我想要的是将一年的价值划分为几个月,每个月都会收到与其 duration 成比例的分数。31/366 * x
即,我希望将年份值拆分为,29/366 * x
等月份:
2020-01 31
2020-02 29
...
2020-11 30
2020-12 31
Freq: M, dtype: float64
有没有办法做到这一点?
- 夏令时
第二种情况是在 DST 转换中,它实际上已经在我的初始示例中显示。2020-03-29
比我的时区中的其他三月天短 1 小时,因此它实际上应该比其他天收到更小的三月值。
尽管它与情况 1 是同一类型的问题,但我怀疑它会更难解决。
编辑:我找到了解决情况 1 的方法,但不是情况 2;在这个问题下面看到我的答案。在改进我的答案以及包括第二种情况方面仍然感谢帮助。
如果我们找到了一种稳健的方法来做这件事,但它有点详细,我可能是一个很好的请求功能(或者尝试通过拉取请求自己添加它),因为它似乎是一个很好的补充。因此,扩展PeriodIndexResampler
api 以允许.distribute()
具有此功能的方法,除了.ffill()
,sum()
等.mean()
方法。