Pandas:在数据框中添加周日期

3

I have a df like, which has such rows:

    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

and two datetime objects:

start_date:

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

结束日期:

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

我要如何获得一个类似的数据框,基本上就是在每一行中添加从起始日期到结束日期的周日期:

    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
3个回答

5

生成 date_range 和交叉merge

  1. 在 pandas 版本 >= 1.2x 中,我们现在可以向 merge 函数传递一个可选参数 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

2

我的做法是首先创建一个包含两个日期之间所有日期的列表,并将其作为新列添加到数据框中,然后使用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
...
...

1

我的解决方案步骤:

  1. 创建所有日期的列表
  2. 将列表转换为 DataFrame
  3. 添加“key”列以进行合并
  4. pd.merge 两个 DataFrame(外部连接)
  5. 删除“key”列
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接