pandas:pd.date_range输出错误

时间:2016-12-30 06:59:51

标签: python loops datetime pandas date-range

我的数据集包含3列IDvrddatenddat和21000行。

ID       vrddat      enddat
1       2015.01.01  2015.01.03    
2       2015.03.01  2015.03.03 

PS:每个ID可以有多个vrddat和enddat。

我需要输出如下:

ID      vrddat      enddat       day
1    2015.01.01   2015.01.03  2015.01.01
1    2015.01.01   2015.01.03  2015.01.02
1    2015.01.01   2015.01.03  2015.01.03
2    2015.03.01   2015.03.03  2015.03.01
2    2015.03.01   2015.03.03  2015.03.02
2    2015.03.01   2015.03.03  2015.03.03

我使用以下代码来获得上面的输出

for index,row in data.iterrows():
    data_2 = pd.DataFrame(pd.date_range(row['vrddat'],row['enddat'], freq ='D'))

使用上面的代码我只得到98行,但理想情况下输出应该包含比输入更多的行。任何人都可以提出为什么我会得到这种输出。我的代码是不是每行迭代一次?如何在输出中获得IDvrddatenddat个变量?

请建议。

1 个答案:

答案 0 :(得分:1)

您可以使用vrddatenddat两个列的第一个投射to_datetime,然后使用itertuplesconcat来创建新的展开DataFrame。最后merge,但必须ID中的df是唯一的。

df.vrddat = pd.to_datetime(df.vrddat)
df.enddat = pd.to_datetime(df.enddat)

df1 = pd.concat([pd.Series(r.ID,pd.date_range(r.vrddat, r.enddat)) for r in df.itertuples()])
        .reset_index()
df1.columns = ['day','ID']
print (df1)
         day  ID
0 2015-01-01   1
1 2015-01-02   1
2 2015-01-03   1
3 2015-03-01   2
4 2015-03-02   2
5 2015-03-03   2

print (pd.merge(df,df1, on='ID', how='left'))
   ID     vrddat     enddat        day
0   1 2015-01-01 2015-01-03 2015-01-01
1   1 2015-01-01 2015-01-03 2015-01-02
2   1 2015-01-01 2015-01-03 2015-01-03
3   2 2015-03-01 2015-03-03 2015-03-01
4   2 2015-03-01 2015-03-03 2015-03-02
5   2 2015-03-01 2015-03-03 2015-03-03

如果ID不唯一,可以使用unique索引进行合并:

df.vrddat = pd.to_datetime(df.vrddat)
df.enddat = pd.to_datetime(df.enddat)
df = df.reset_index()

df1=pd.concat([pd.Series(r.index,pd.date_range(r.vrddat,r.enddat)) for r in df.itertuples()])
      .reset_index()
df1.columns = ['day','index']
print (df1)
         day  index
0 2015-01-01      0
1 2015-01-02      0
2 2015-01-03      0
3 2015-03-01      1
4 2015-03-02      1
5 2015-03-03      1

print (pd.merge(df,df1, on='index', how='left').drop('index', axis=1))
   ID     vrddat     enddat        day
0   1 2015-01-01 2015-01-03 2015-01-01
1   1 2015-01-01 2015-01-03 2015-01-02
2   1 2015-01-01 2015-01-03 2015-01-03
3   2 2015-03-01 2015-03-03 2015-03-01
4   2 2015-03-01 2015-03-03 2015-03-02
5   2 2015-03-01 2015-03-03 2015-03-03