【问题标题】:pandas: add week dates with dataframe熊猫:用数据框添加星期日期
【发布时间】:2021-07-25 20:42:06
【问题描述】:

我有一个类似 df 的行:

    p_id    m_id    x_id    g_id    u_id
0   2       NaN     1408    7       121
1   3       1259    117     23      315
2   3       1259    221     9       718
3   3       1259    397     76      367

还有两个日期时间对象:

开始日期:

datetime.datetime(2021, 5, 25, 0, 0)

结束日期:

datetime.datetime(2021, 5, 29, 0, 0)

我如何获得类似的 df,基本上(将每行从 start_date 到 end_date 的周日期添加):

    p_id    m_id    x_id    g_id    u_id  s_date
0   2       NaN     1408    7       121   2021-05-25
1   2       NaN     1408    7       121   2021-05-26
2   2       NaN     1408    7       121   2021-05-27
3   2       NaN     1408    7       121   2021-05-28
4   2       NaN     1408    7       121   2021-05-29

5   3       1259    117     23      315   2021-05-25
6   3       1259    117     23      315   2021-05-26
7   3       1259    117     23      315   2021-05-27
8   3       1259    117     23      315   2021-05-28
9   3       1259    117     23      315   2021-05-29
.
.
15  3       1259    397     76      367   2021-05-25
16  3       1259    397     76      367   2021-05-26
17  3       1259    397     76      367   2021-05-27
18  3       1259    397     76      367   2021-05-28
19  3       1259    397     76      367   2021-05-29

【问题讨论】:

    标签: python python-3.x pandas date


    【解决方案1】:

    我要做的方法是首先创建两个日期之间所有日期的列表,并将其作为新列添加到数据框中,然后使用explode 分解成行:

    这是一个例子:

    df['s_date'] = [pd.date_range(datetime(2021, 5, 25, 0, 0),datetime(2021, 5, 29, 0, 0),freq='d')] * len(df)
    df = df.explode('s_date')
    

    输出:

    
        id  start   score   date
    0   id1     NaN     3   2021-05-25
    0   id1     NaN     3   2021-05-26
    0   id1     NaN     3   2021-05-27
    0   id1     NaN     3   2021-05-28
    0   id1     NaN     3   2021-05-29
    1   id2     12.0    1   2021-05-25
    1   id2     12.0    1   2021-05-26
    1   id2     12.0    1   2021-05-27
    1   id2     12.0    1   2021-05-28
    1   id2     12.0    1   2021-05-29
    2   id3     11.0    8   2021-05-25
    2   id3     11.0    8   2021-05-26
    2   id3     11.0    8   2021-05-27
    2   id3     11.0    8   2021-05-28
    2   id3     11.0    8   2021-05-29
    ...
    ...
    

    【讨论】:

      【解决方案2】:

      我的解决方案中的步骤:

      1. 创建所有日期的列表
      2. 将列表转换为DataFrame
      3. 为合并添加“键”列
      4. pd.merge两个DataFrame(外连接)
      5. 删除“键”列
      import pandas as pd
      from datetime import datetime, timedelta
      # example to your df
      a = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]
      a_df = pd.DataFrame(a)
      
      start_date = datetime.strptime('2021-05-01', '%Y-%m-%d')
      end_date = datetime.strptime('2021-06-01', '%Y-%m-%d')
      num_of_days = (end_date - start_date).days
      
      date_df = pd.DataFrame([start_date + timedelta(days=x) for x in range(num_of_days)], columns=['date'])
      a_df = pd.DataFrame(a)
      
      a_df['key'] = 0
      date_df['key'] = 0
      
      a_df = a_df.merge(date_df, on='key', how='outer')
      a_df = a_df.drop('key', 1)
      
      a_df
      

      【讨论】:

        【解决方案3】:

        生成date_range并交叉merge

        1. 在 pandas 版本 >= 1.2x 中,要执行交叉合并,我们现在可以将可选参数 how='cross' 传递给合并函数
        dates = pd.date_range(start_date, end_date)
        df.merge(dates.to_series(name='s_date'), how='cross')
        
        1. 对于 pandas 版本 1.2x,我们必须创建一个临时合并键才能执行 cross 合并
        dates = pd.date_range(start_date, end_date)
        df.assign(k=1).merge(dates.to_frame(name='s_date').assign(k=1), on='k').drop('k', 1)
        

            p_id    m_id  x_id  g_id  u_id     s_date
        0      2     NaN  1408     7   121 2021-05-25
        1      2     NaN  1408     7   121 2021-05-26
        2      2     NaN  1408     7   121 2021-05-27
        3      2     NaN  1408     7   121 2021-05-28
        4      2     NaN  1408     7   121 2021-05-29
        5      3  1259.0   117    23   315 2021-05-25
        6      3  1259.0   117    23   315 2021-05-26
        7      3  1259.0   117    23   315 2021-05-27
        8      3  1259.0   117    23   315 2021-05-28
        9      3  1259.0   117    23   315 2021-05-29
        10     3  1259.0   221     9   718 2021-05-25
        11     3  1259.0   221     9   718 2021-05-26
        12     3  1259.0   221     9   718 2021-05-27
        13     3  1259.0   221     9   718 2021-05-28
        14     3  1259.0   221     9   718 2021-05-29
        15     3  1259.0   397    76   367 2021-05-25
        16     3  1259.0   397    76   367 2021-05-26
        17     3  1259.0   397    76   367 2021-05-27
        18     3  1259.0   397    76   367 2021-05-28
        19     3  1259.0   397    76   367 2021-05-29
        

        【讨论】:

          猜你喜欢
          • 2017-11-03
          • 1970-01-01
          • 1970-01-01
          • 2020-01-14
          • 2021-10-21
          • 2017-06-05
          • 2017-08-09
          • 2017-08-03
          • 2021-03-12
          相关资源
          最近更新 更多