在 2 个日期之间插入重复的行数据 Pandas

Insert Duplicate Row Data between 2 Dates Pandas

我正在尝试找到一种方法,可以在日期之间的每一天连续复制所有数据。开始日期和结束日期。

这是数据集:

Name            Medication  Start       End         Dose
James Jameson   Depakote    2013-07-01  2015-04-13  1500
James Jameson   Depakote    2015-04-14  2015-04-22  1750
James Jameson   Depakote    2015-04-23  2015-06-30  2000
James Jameson   Naltrexone  2013-07-01  2015-06-30  100
James Jameson   Trazodone   2013-07-01  2015-06-30  300
James Jameson   Xanex       2013-07-01  2014-02-01  0
James Jameson   Xanex       2014-02-02  2015-06-30  1
James Jameson   Zoloft      2014-03-21  2015-06-30  100
James Jameson   Zoloft      2014-07-01  2014-03-20  50

我想做的是在开始值和结束值之间的每一天重复该行,增加日期。我觉得我可以通过日期范围和追加的某种组合来做到这一点,但我找不到整行的解决方案。

示例结果:

Name            Medication  Start       End         Dose
James Jameson   Depakote    2013-07-01  2015-04-13  1500
James Jameson   Depakote    2013-07-02  2015-04-13  1500
James Jameson   Depakote    2013-07-03  2015-04-13  1500
James Jameson   Depakote    2013-07-x   2015-04-13  1500
.
.
.
James Jameson   Depakote    2015-04-13  2015-04-13  1500
James Jameson   Depakote    2015-04-14  2015-04-22  1750
James Jameson   Depakote    2015-04-15  2015-04-22  1750
James Jameson   Depakote    2015-04-16  2015-04-22  1750
James Jameson   Depakote    2015-04-x   2015-04-22  1750
.
.
.
James Jameson   Depakote    2015-04-22  2015-04-22  1750
James Jameson   Depakote    2015-04-23  2015-06-30  2000
James Jameson   Naltrexone  2013-07-01  2015-06-30  100
James Jameson   Trazodone   2013-07-01  2015-06-30  300
James Jameson   Xanex       2013-07-01  2014-02-01  0
James Jameson   Xanex       2014-02-02  2015-06-30  1
James Jameson   Zoloft      2014-03-21  2015-06-30  100
James Jameson   Zoloft      2014-07-01  2014-03-20  50

因此最终它将为原始数据框中开始日期和结束日期之间的每一天创建一个新的重复行。

reindexgroupby

结合使用
df = pd.DataFrame({'Name': {0: 'James Jameson', 1: 'James Jameson', 2: 'James Jameson', 3: 'James Jameson', 4: 'James Jameson'}, 'Medication': {0: 'Depakote', 1: 'Depakote', 2: 'Depakote', 3: 'Naltrexone', 4: 'Trazodone'}, 'Start': {0: '2013-07-01', 1: '2015-04-14', 2: '2015-04-23', 3: '2013-07-01', 4: '2013-07-01'}, 'End': {0: '2015-04-13', 1: '2015-04-22', 2: '2015-06-30', 3: '2015-06-30', 4: '2015-06-30'}, 'Dose': {0: 1500, 1: 1750, 2: 2000, 3: 100, 4: 300}})
df[['Start','End']] = df[['Start','End']].apply(pd.to_datetime)


df2 = pd.concat([g.set_index('Start').reindex(pd.date_range(g['Start'].min(), g['End'].max(), freq='d'), method='ffill').reset_index().rename({'index':'Start'}, axis=1)
                 for _, g in df.groupby(['Name','Medication','Dose'])],
                axis=0)

回答下面问题的更多细节——列表理解实际上就是把这个 for 循环放在一行上。有很多文本,但它看起来确实很复杂,因为它没有将值存储在变量中——尽管这样做可能会使正在发生的事情更清楚一些。 :

# undoing the list comprehension...
sub_dfs = []
for group_value, group_df in df.groupby(['Name','Medication','Dose']):
    print(group_value)
    # if not using the group_value for anything, you can just put '_' 
    # to unpack the .groupby() tuple but not bother naming it
    
    # construct date range
    group_start_date = group_df['Start'].min()
    group_end_date = group_df['End'].max()
    group_date_range = pd.date_range(group_start_date, group_end_date, freq='d')
    
    new_group_df = group_df.set_index('Start').reindex(group_date_range, method='ffill').reset_index().rename({'index':'Start'}, axis=1)
    sub_dfs.append(new_group_df)
    
df2b = pd.concat(sub_dfs, axis=0)

我想这就是你想要的。首先利用 pd.to_datetime 转换为 datetime 对象,然后创建一个空列表来存储值。

import pandas as pd

df=pd.read_csv("example_data.csv")

df["Start"]=pd.to_datetime(df["Start"])
df["End"]=pd.to_datetime(df["End"])
row_list = []

然后使用 pd.date_range

在开始和结束之间使用嵌套 for 遍历每一行的日期范围
for row in df.index:
    for date in pd.date_range(start=df["Start"][row], end=df["End"][row]):
        temp_dict = {"Name": df.Name[row], "Medication": df.Medication[row], "Start" : date,
            "End" : df.End[row], "Dose" : df.Dose[row]}
        row_list.append(temp_dict)

最后使用之前创建和填充的列表创建一个新数据框

df2 = pd.DataFrame(row_list)

请注意,这比使用 pd.append

快得多