在 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
因此最终它将为原始数据框中开始日期和结束日期之间的每一天创建一个新的重复行。
将 reindex
与 groupby
结合使用
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
快得多
我正在尝试找到一种方法,可以在日期之间的每一天连续复制所有数据。开始日期和结束日期。
这是数据集:
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
因此最终它将为原始数据框中开始日期和结束日期之间的每一天创建一个新的重复行。
将 reindex
与 groupby
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
快得多