生成日期之间缺少的连续日期

时间:2017-12-15 10:05:34

标签: python pandas

我有一个动态生成的文件(即文件头保持不变但值发生变化)。例如,让文件为以下形式:

ID,CLASS,DATE,MRK
1,321,02/12/2016,30
2,321,05/12/2016,40
3,321,06/12/2016,0
4,321,07/12/2016,60
5,321,10/12/2016,70
6,876,5/12/2016,100
7,876,7/12/2016,80

CLASS 321的通知有一些缺失日期,即03/12/201604/12/201608/12/201609/12/2016。我正在尝试在相应位置插入缺少的日期,其中MRK的对应值为0。预期的输出是这样的:

ID,CLASS,DATE,MRK
1,321,02/12/2016,30
2,321,03/12/2016,0
3,321,04/12/2016,0
4,321,05/12/2016,40
5,321,06/12/2016,0
6,321,07/12/2016,60
7,321,08/12/2016,0
8,321,09/12/2016,0
9,321,10/12/2016,70
10,876,5/12/2016,100
11,876,6/12/2016,0
12,876,7/12/2016,80

这是我到目前为止所提出的:

import pandas as pd

df = pd.read_csv('In.txt')
resampled_df = df.resample('D').mean()
print resampled_df

但我得到例外:

TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex'

有人可以在这里帮助一个蟒蛇新手吗?

2 个答案:

答案 0 :(得分:4)

像这样阅读你的CSV -

df = pd.read_csv('file.csv', 
                 sep=',', 
                 parse_dates=['DATE'],  
                 dayfirst=True,         # this is important since you have days first
                 index_col=['DATE'])

现在,请致电groupby + resample + first,并结束松散的目标 -

df = df.groupby('CLASS').resample('1D')[['MRK']].first() 

df.ID = np.arange(1, len(df) + 1)
df.MRK = df.MRK.fillna(0).astype(int)

df.reset_index()

    CLASS       DATE  ID  MRK
0     321 2016-12-02   1   30
1     321 2016-12-03   2    0
2     321 2016-12-04   3    0
3     321 2016-12-05   4   40
4     321 2016-12-06   5    0
5     321 2016-12-07   6   60
6     321 2016-12-08   7    0
7     321 2016-12-09   8    0
8     321 2016-12-10   9   70
9     876 2016-12-05  10  100
10    876 2016-12-06  11    0
11    876 2016-12-07  12   80

特别是,MRK需要fillna。其余的可以向前填补。

如果列的顺序很重要,这是另一个版本。

df = pd.read_csv('file.csv', 
                 sep=',', 
                 parse_dates=['DATE'],  
                 dayfirst=True)

c = df.columns
df = df.set_index('DATE').groupby('CLASS').resample('1D')[['MRK']].first()

df['MRK'] = df.MRK.fillna(0).astype(int)
df['ID'] = np.arange(1, len(df) + 1)
df = df.reset_index().reindex(columns=c)
df['DATE'] = df['DATE'].dt.strftime('%d/%m/%Y')

df

    ID  CLASS        DATE  MRK
0    1    321  02/12/2016   30
1    2    321  03/12/2016    0
2    3    321  04/12/2016    0
3    4    321  05/12/2016   40
4    5    321  06/12/2016    0
5    6    321  07/12/2016   60
6    7    321  08/12/2016    0
7    8    321  09/12/2016    0
8    9    321  10/12/2016   70
9   10    876  05/12/2016  100
10  11    876  06/12/2016    0
11  12    876  07/12/2016   80

答案 1 :(得分:2)

首先转换为日期时间,然后按CLASSgroupby转换为resample,最后按insert添加列ID

df['DATE'] = pd.to_datetime(df['DATE'], dayfirst=True)

df = (df.set_index('DATE')
        .groupby('CLASS')
        .resample('d')['MRK']
        .asfreq()
        .fillna(0)
        .astype(int)
        .reset_index())

df.insert(0, 'ID', range(1, len(df) + 1))
print (df)
    ID  CLASS       DATE  MRK
0    1    321 2016-12-02   30
1    2    321 2016-12-03    0
2    3    321 2016-12-04    0
3    4    321 2016-12-05   40
4    5    321 2016-12-06    0
5    6    321 2016-12-07   60
6    7    321 2016-12-08    0
7    8    321 2016-12-09    0
8    9    321 2016-12-10   70
9   10    876 2016-12-05  100
10  11    876 2016-12-06    0
11  12    876 2016-12-07   80

替代解决方案:

df = (df.set_index('DATE')
        .groupby('CLASS')
        .resample('d')['MRK']
        .first()
        .fillna(0)
        .astype(int)
        .reset_index())

df.insert(0, 'ID', range(1, len(df) + 1))
print (df)
    ID  CLASS       DATE  MRK
0    1    321 2016-12-02   30
1    2    321 2016-12-03    0
2    3    321 2016-12-04    0
3    4    321 2016-12-05   40
4    5    321 2016-12-06    0
5    6    321 2016-12-07   60
6    7    321 2016-12-08    0
7    8    321 2016-12-09    0
8    9    321 2016-12-10   70
9   10    876 2016-12-05  100
10  11    876 2016-12-06    0
11  12    876 2016-12-07   80

最后使用与输入相同的格式strftime

df['DATE'] = df['DATE'].dt.strftime('%d/%m/%Y')
print (df)
    ID  CLASS        DATE  MRK
0    1    321  02/12/2016   30
1    2    321  03/12/2016    0
2    3    321  04/12/2016    0
3    4    321  05/12/2016   40
4    5    321  06/12/2016    0
5    6    321  07/12/2016   60
6    7    321  08/12/2016    0
7    8    321  09/12/2016    0
8    9    321  10/12/2016   70
9   10    876  05/12/2016  100
10  11    876  06/12/2016    0
11  12    876  07/12/2016   80