Python 如何做一个;“加权上采样”;在《熊猫》系列中?

Python 如何做一个;“加权上采样”;在《熊猫》系列中?,python,pandas,pandas-resample,Python,Pandas,Pandas Resample,我在python中有一个函数,用于在上采样时分发值。例如,要将我的汽车行驶距离从每月增加到每天,请执行以下操作: def分配(df,freq:str): #如果有更简单的方法,请发表评论 df_new=df.resample(freq.asfreq().fillna(0) 返回df_new.groupby(pd.Grouper(freq=df.index.freq)).transform(np.mean) 作为pd进口熊猫 将numpy作为np导入 距离=局部放电系列([300300],局部放电

我在python中有一个函数,用于在上采样时分发值。例如,要将我的汽车行驶距离从每月增加到每天,请执行以下操作:

def分配(df,freq:str):
#如果有更简单的方法,请发表评论
df_new=df.resample(freq.asfreq().fillna(0)
返回df_new.groupby(pd.Grouper(freq=df.index.freq)).transform(np.mean)
作为pd进口熊猫
将numpy作为np导入
距离=局部放电系列([300300],局部放电周期\范围('2020-02',频率='M',周期=2))
分布(距离“D”)
该函数将每个月的值平均除以该月的天数,在本例中,这将导致
2020-02
值除以29,而
2020-03
值除以31


然而,当上采样到周期持续时间不均匀的频率时,这会给我带来不想要的结果。此属性有两种情况:

  • 年复一月:
  • distances2=pd.Series([366],pd.PeriodIndex(['2020',freq='Y'))
    分布(距离2,'M')
    
    我想要的是将一年的值除以几个月,每个月得到与其持续时间成比例的分数。i、 例如,我希望将年份值按月份拆分为
    31/366*x
    29/366*x
    ,等等:

    2020-01    31
    2020-02    29
               ...
    2020-11    30
    2020-12    31
    Freq: M, dtype: float64
    
    有办法做到这一点吗?

  • DST
  • 第二种情况是在DST转换中,它实际上已经在我的初始示例中显示出来了<代码>2020-03-29比我所在时区的其他三月份短1小时,因此它实际接收到的三月值应该比其他日子小

    虽然这和情况1是同一类型的问题,但我怀疑这将很难解决


    编辑:我找到了解决情况1的方法,但没有解决情况2;请看下面这个问题的答案。在改进我的答案,包括第二种情况方面,我仍然很感激你的帮助



    如果我们找到了一种健壮的方法来实现这一点,这可能是一个很好的特性来请求(或者尝试自己添加一个pull请求),因为它似乎是一个很好的添加。因此,为了扩展
    PeriodIndexResampler
    api,允许使用
    .distribute()
    方法,除了
    .ffill()
    sum()
    平均值()
    等方法之外,还可以使用
    .distribute()
    方法来解决问题1,我发现我可以先向上采样到具有统一持续时间的更高频率周期,例如“D”,然后再向下采样到想要的频率:

    def分配(df,freq:str):
    #现在真的很疯狂
    df_D=df.resample('D').asfreq().fillna(0)
    df_D_spread=df_D.groupby(pd.Grouper(freq=df.index.freq)).transform(np.mean)
    返回df_D_spread.groupby(pd.Grouper(freq=freq)).sum()
    距离2=pd.系列([366],pd.周期索引([2020],频率为Y'))
    分布(距离2,'M')
    
    但是/备注:

    • 它很复杂,很难阅读。而且也浪费了大量的内存空间,一年内可以扩展到366行或365行。一定有更好的办法吗

    • 它没有解决第二个问题。
      事实上,我选择了
      'D'
      而不是
      'H'
      ,因为时段不支持时区。事实上,并非所有的日子都是等长的,每当我们找到一种方法来包含这一事实时,我们可能需要将代码向上采样到
      'H'
      (甚至对于分数时区
      '15T'


    你的第一个问题很简单,是的,有一个较短的方法:
    dist/=dist.index.days\u in_month
    result=dist.resample('D').asfreq().ffill()
    至于你的第二个问题,要求是什么还不太清楚,你能添加一个数据样本或打开一个新问题吗,对于你的第二个问题,你可以先向上采样到几个月(x除以12),然后你可以在我的第一条评论中使用这个解决方案,这个解决方案会逐月向上采样。这应该行得通,不是吗?谢谢@cs95的回答。是否有其他方法获取除法器(
    dist.index.days\u in\u month
    )的方法?我想把它转换成一个以新频率为参数的函数,因此它并不总是从
    M
    月到
    D
    天。我为问题2添加了一个示例;你的建议在这里不起作用。除非你推断出现有分布的频率。然后您可以创建一个函数来选择正确的除法器。有很多方法可以很容易地推断出频率,一些快速的谷歌搜索就会找到答案(不在我的办公桌上,我自己也不能分享链接)。
    2020-01    30.5
    2020-02    30.5
    ...         ...
    2020-11    30.5
    2020-12    30.5
    Freq: M, dtype: float64
    
    2020-01    31
    2020-02    29
               ...
    2020-11    30
    2020-12    31
    Freq: M, dtype: float64
    
    2020-01    31.0
    2020-02    29.0
    ...         ...
    2020-11    30.0
    2020-12    31.0
    Freq: M, dtype: float64