重新索引并填写缺失的日期

时间:2016-10-24 22:22:29

标签: python date pandas dataframe

我有一个采用这种格式的DataFrame。

       country_txt  multiple  success  nkill  nwound  property      dates  \
1970Q1       Italy         0        1    0.0     0.0         0 1970-01-01   
1970Q1       Italy         0        0    0.0     0.0         1 1970-01-01   
1970Q4       Italy         0        0    0.0     0.0         1 1970-04-01   
1971Q1       Italy         0        1    0.0     0.0         1 1971-01-01   
1971Q3       Italy         0        1    0.0     0.0         1 1971-03-01 

此DataFrame的索引是我使用PeriodIndex创建的季度的年份。 dates列表示年份和季度,月份的日期无关紧要。我想总结每个季度的所有其他专栏。通常这不是问题,因为我可以做italy.groupby('dates').sum()。但是,我得到的输出是

            multiple  success  nkill  nwound  property  
dates                                                             
1970-01-01         0        1    0.0     0.0         1           
1970-04-01         0        0    0.0     0.0         1           
1971-01-01         0        1    0.0     0.0         1   

现在的问题是我想填写每个季度缺少的值,这些值没有出现,所以输出看起来像这样,

                multiple  success  nkill  nwound  property  
dates                                                             
1970-01-01         0        1    0.0     0.0         1 
1970-02-01         0        0    0.0     0.0         0
1970-03-01         0        0    0.0     0.0         0
1970-04-01         0        0    0.0     0.0         1           
1971-01-01         0        1    0.0     0.0         1 

我查了之前的问题,发现人们建议我这样做df.reindex(pd.date_range("1970-01-01", "2015-12-31"), fill_value = 0)。问题是,这将为我的数据提供额外的行,因为我每天都会有数据,这意味着我必须找到一种方法来重新整合数据。那么,如果不创造所有这些每日0并且找到一种方法来按季度再次总结所有内容,我将如何实现这一目标呢?

作为参考,dates列的创建方法是首先将原始月份列更改为1-4中的值(表示季度),然后通过执行此操作转换为timedelta格式

df['dates'] = df.iyear.astype(str).str.cat(df.imonth.astype(str))
df['dates'] = pd.to_datetime(df['dates'], format = '%Y%m')

1 个答案:

答案 0 :(得分:2)

UPDATE:从字符串索引解析实际日期。它也适用于旧的Pandas版本:

In [212]: df.set_index(pd.to_datetime(df.index)).resample('QS').sum().fillna(0)
Out[212]:
            multiple  success  nkill  nwound  property
idx
1970-01-01       0.0      1.0    0.0     0.0       1.0
1970-04-01       0.0      0.0    0.0     0.0       0.0
1970-07-01       0.0      0.0    0.0     0.0       0.0
1970-10-01       0.0      0.0    0.0     0.0       1.0
1971-01-01       0.0      1.0    0.0     0.0       1.0
1971-04-01       0.0      0.0    0.0     0.0       0.0
1971-07-01       0.0      1.0    0.0     0.0       1.0

OLD回答 :(假设dates列包含实际日期)。它使用新的Pandas 0.19.0功能:.resample(..., on='column_name')

试试这个:

In [205]: df.resample('QS', on='dates').sum().fillna(0)
Out[205]:
            multiple  success  nkill  nwound  property
dates
1970-01-01       0.0      1.0    0.0     0.0       1.0
1970-04-01       0.0      0.0    0.0     0.0       1.0
1970-07-01       0.0      0.0    0.0     0.0       0.0
1970-10-01       0.0      0.0    0.0     0.0       0.0
1971-01-01       0.0      2.0    0.0     0.0       2.0

或重新采样"每月":

In [207]: df.resample('QS', on='dates').sum().resample('MS').sum().fillna(0)
Out[207]:
            multiple  success  nkill  nwound  property
dates
1970-01-01       0.0      1.0    0.0     0.0       1.0
1970-02-01       0.0      0.0    0.0     0.0       0.0
1970-03-01       0.0      0.0    0.0     0.0       0.0
1970-04-01       0.0      0.0    0.0     0.0       1.0
1970-05-01       0.0      0.0    0.0     0.0       0.0
1970-06-01       0.0      0.0    0.0     0.0       0.0
1970-07-01       0.0      0.0    0.0     0.0       0.0
1970-08-01       0.0      0.0    0.0     0.0       0.0
1970-09-01       0.0      0.0    0.0     0.0       0.0
1970-10-01       0.0      0.0    0.0     0.0       0.0
1970-11-01       0.0      0.0    0.0     0.0       0.0
1970-12-01       0.0      0.0    0.0     0.0       0.0
1971-01-01       0.0      2.0    0.0     0.0       2.0