python - pandas Grouper 未按预期进行上采样

标签 python pandas grouping pandas-groupby multi-index

考虑一个具有 MultiIndex 的系列,该系列在级别 0 上提供自然分组值,在级别 1 上提供时间序列:

s = pd.Series(range(12), index=pd.MultiIndex.from_product([['a','b','c'],
              pd.date_range(start='2019-01-01', freq='3D', periods=4)], names=['grp','ts']))
print(s)
grp  ts
a    2019-01-01     0
     2019-01-04     1
     2019-01-07     2
     2019-01-10     3
b    2019-01-01     4
     2019-01-04     5
     2019-01-07     6
     2019-01-10     7
c    2019-01-01     8
     2019-01-04     9
     2019-01-07    10
     2019-01-10    11
Length: 12, dtype: int64

我想对每个外部索引值的时间序列进行上采样,例如使用简单的前向填充操作:

s.groupby(['grp', pd.Grouper(level=1, freq='D')]).ffill()

这会产生意想不到的结果;也就是说,它不做任何事情。结果正是 s 而不是我想要的:

grp ts
a   2019-01-01   0
    2019-01-02   0
    2019-01-03   0
    2019-01-04   1
    2019-01-05   1
    2019-01-06   1
    2019-01-07   2
    2019-01-08   2
    2019-01-09   2
    2019-01-10   3
b   2019-01-01   4
    2019-01-02   4
    2019-01-03   4
    2019-01-04   5
    2019-01-05   5
    2019-01-06   5
    2019-01-07   6
    2019-01-08   6
    2019-01-09   6
    2019-01-10   7
c   2019-01-01   8
    2019-01-02   8
    2019-01-03   8
    2019-01-04   9
    2019-01-05   9
    2019-01-06   9
    2019-01-07  10
    2019-01-08  10
    2019-01-09  10
    2019-01-10  11
Length: 30, dtype: int64

我可以更改 Grouper freq 或 resample 函数以达到相同的效果。我发现的一个解决方法是通过创造性的欺骗来强制每个组使用简单的时间序列索引(感谢艾伦提供答案 https://stackoverflow.com/a/44719843/3109201 ):

s.reset_index(level=1).groupby('grp').apply(lambda s: s.set_index('ts').resample('D').ffill())

这与我最初要求的略有不同,因为它返回一个 DataFrame:

                 0
grp ts
a   2019-01-01   0
    2019-01-02   0
    2019-01-03   0
    2019-01-04   1
    2019-01-05   1
    2019-01-06   1
    2019-01-07   2
    2019-01-08   2
    2019-01-09   2
    2019-01-10   3
b   2019-01-01   4
    2019-01-02   4
    2019-01-03   4
    2019-01-04   5
    2019-01-05   5
    2019-01-06   5
    2019-01-07   6
    2019-01-08   6
    2019-01-09   6
    2019-01-10   7
c   2019-01-01   8
    2019-01-02   8
    2019-01-03   8
    2019-01-04   9
    2019-01-05   9
    2019-01-06   9
    2019-01-07  10
    2019-01-08  10
    2019-01-09  10
    2019-01-10  11

[30 rows x 1 columns]

我可以并且将会使用此解决方法,但我想知道为什么更简单(并且坦率地说更优雅)的方法不起作用。

最佳答案

使用series.asfreq()来满足缺失的日期。

def filldates(s_in):
  s_in.reset_index(level="grp",drop=True,inplace=True)
  s_in= s_in.asfreq("1D",method='ffill')
  return s_in
s.groupby(level=0).apply(filldates)

关于python - pandas Grouper 未按预期进行上采样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58014927/

相关文章:

python - 支持在 Python 中使用的操作系统语言环境

python - 我遇到了一个关于 django Queryset 的棘手问题

python - 将 dict 的嵌套列表展平为 Pandas Dataframe

python - Pandas:以 pythonic 方式拆分字符串

php - 按列中的子数组对数据行进行分组,并创建具有可变深度的子集

excel - 如何在Excel中的列中应用分组值

c# - 如何对这些 XDocuments 进行分组?

python - 跳出当前迭代的 for 循环

python - Django 模型字段验证

python - 反转数据框中的行值