【问题标题】:How to extract a DataFrame using start and end dates with Pandas如何使用 Pandas 的开始和结束日期提取 DataFrame
【发布时间】:2018-08-09 15:41:46
【问题描述】:

我们如何使用开始和结束日期提取DataFrame 并实现此输出?

输入

id  start  end
1   2009   2014
2   2010   2012

输出

id  data
1   2009
1   2010
1   2011
1   2012
1   2013
1   2014
2   2010
2   2011
2   2012

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    创建按['id'] 分组的年份之间的日期枚举。索引的额外重新格式化是可选的

    import numpy as np
    import pandas as pd
    melted = df.groupby('id').apply(lambda x:pd.Series(np.arange(x['start'],x['end']+1)))
    
    melted.index = melted.index.droplevel(1)
    
    id
    1    2009
    1    2010
    1    2011
    1    2012
    1    2013
    1    2014
    2    2010
    2    2011
    2    2012
    

    【讨论】:

    • 能否用date_range函数得到
    【解决方案2】:

    用途:

    df1 = (pd.concat([pd.Series(r.id,np.arange(r.start, r.end + 1)) for r in df.itertuples()])
            .reset_index())
    df1.columns = ['data','id']
    df1 = df1[['id','data']]
    print (df1)
       id  data
    0   1  2009
    1   1  2010
    2   1  2011
    3   1  2012
    4   1  2013
    5   1  2014
    6   2  2010
    7   2  2011
    8   2  2012
    

    【讨论】:

    • 开始和结束是带有年份的日期。如果年份和月份是不同的输出
    • 我们能否最小化这个逻辑的逻辑和时间复杂度。df=pd.concat([pd.DataFrame({'start': pd.date_range(row.start, row.end, freq= "AS"), 'series_id': row.series_id}, columns=['start', 'series_id']) for i, row in df.iterrows()], ignore_index=True)
    • @raam 我使用 itertuples 因为像 iterrows 这样的性能更好,但是如果输入数据帧很小,那么 iterrows 是不错的选择。输入df的大小是多少?
    • 数据量大,最小50k个索引。
    • 我们可以减少或者我们可以对此有不同的逻辑 df1 = (pd.concat([pd.Series(r.id, pd.date_range(r.start, r.end, freq=' AS')) for r in df.itertuples()]) .reset_index())
    【解决方案3】:

    有点难理解,我觉得这个应该比apply快一点

    通过使用reindexrepeat

    df.reindex(df.index.repeat(df['end']-df['start']+1)).assign(year=lambda x : x['start']+x.groupby('id').cumcount())
    Out[453]: 
       id  start   end  year
    0   1   2009  2014  2009
    0   1   2009  2014  2010
    0   1   2009  2014  2011
    0   1   2009  2014  2012
    0   1   2009  2014  2013
    0   1   2009  2014  2014
    1   2   2010  2012  2010
    1   2   2010  2012  2011
    1   2   2010  2012  2012
    

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 2022-12-13
      • 2021-05-12
      相关资源
      最近更新 更多