【问题标题】:pandas :pd.date_range output error熊猫:pd.date_range 输出错误
【发布时间】:2017-05-14 12:12:04
【问题描述】:

我有一个包含 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 变量?

请提出建议。

【问题讨论】:

    标签: python loops datetime pandas date-range


    【解决方案1】:

    您可以先使用to_datetime 两个列vrddatenddat,然后使用itertuplesconcat 创建新的扩展DataFrame。最后一个merge,但必须IDdf是唯一的。

    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
    

    【讨论】:

    • 非常感谢您抽出宝贵的时间,您的代码很有帮助您知道为什么我的输出只有 98 行吗?我错过了一些逻辑吗?
    • 我认为你会在每个循环中覆盖 data_2,因此获取最后一个循环的输出 - df 中的最后一行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2016-06-11
    • 2013-05-15
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多