再访Pandas按组别重新编制的日期索引

cedebl8k  于 2023-01-11  发布在  其他
关注(0)|答案(2)|浏览(110)

以前有人问过这个问题,这里提出了一个可行的解决方案Pandas reindex dates in Groupby,过去对我很有效,但现在不起作用了。
因此,为了重述我需要使用日期重新索引 Dataframe 来创建“平衡面板”-不要在任何组中缺少日期-值组合。

import pandas as pd
from datetime import datetime

date1 = datetime.strptime('2023-01-01', '%Y-%m-%d').date()
date2 = datetime.strptime('2023-01-02', '%Y-%m-%d').date()
date3 = datetime.strptime('2023-01-03', '%Y-%m-%d').date()

df = pd.DataFrame({'Date':[date1] * 3 + [date2]  + [date3] * 3,
'Group':['A', 'B', 'C', 'A', 'A', 'B', 'C'],
'Value':[20, 10, 23, 45, 60, 14, 25]})
 
df.set_index('Date', inplace=True)

预期输出为:

df_target = pd.DataFrame({'Date':[date1] * 3 + [date2] * 3  + [date3] * 3,
'Group':['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
'Value':[20, 10, 23, 45, 0, 0, 60, 14, 25]})

df_target.set_index('Date', inplace=True)

尝试的解决方案(注意Assert):

def reindex_by_date(df, freq):
    dates = pd.date_range(start=df.index.min(), end=df.index.max(), freq=freq)
    idx = pd.Index(dates, name='Dates')
    assert dates.duplicated().sum()==0
    return df.reindex(dates, fill_value=0)

df.groupby('Group').apply(reindex_by_date(df, freq='D'))

# this has also been added: .reset_index(drop=True)

产生错误:

ValueError: cannot reindex from a duplicate axis

我甚至检查了标志(这里是True):

df.flags.allows_duplicate_labels
klr1opcd

klr1opcd1#

您在apply中错误地调用了该函数(您没有传递组,而是传递了整个DataFrame)。
这应该是:

df.groupby('Group').apply(lambda g: reindex_by_date(g, freq='D'))

或者:

df.groupby('Group').apply(reindex_by_date, freq='D')

输出:

Group  Value
Group                        
A     2023-01-01     A     20
      2023-01-02     A     45
      2023-01-03     A     60
B     2023-01-01     B     10
      2023-01-02     0      0
      2023-01-03     B     14
C     2023-01-01     C     23
      2023-01-02     0      0
      2023-01-03     C     25

请注意,您必须删除Groupreset_index,以避免将Group中的0重新索引为列:

(df.groupby('Group').apply(reindex_by_date, freq='D')
   .drop(columns='Group').reset_index('Group')
 .rename_axis('Date')
)

输出:

Group  Value
Date                   
2023-01-01     A     20
2023-01-02     A     45
2023-01-03     A     60
2023-01-01     B     10
2023-01-02     B      0
2023-01-03     B     14
2023-01-01     C     23
2023-01-02     C      0
2023-01-03     C     25
f0brbegy

f0brbegy2#

关于:

idx = pd.MultiIndex.from_product(
    [df.index.unique(), df["Group"].unique()],
    names=["Date", "Group"]
)

out = (
    df
    .set_index("Group", append=True)
    .reindex(idx, fill_value=0)
    .reset_index(level=1)
)

输出:

Group  Value
Date
2023-01-01     A     20
2023-01-01     B     10
2023-01-01     C     23
2023-01-02     A     45
2023-01-02     B      0
2023-01-02     C      0
2023-01-03     A     60
2023-01-03     B     14
2023-01-03     C     25

相关问题