按日期更新 DataFrame 中的值
Update values in a DataFrame by values in another by date
我试图制作一个代码来输入项目的版本。
有两个数据框,一个是项目,一个是版本信息。
这是我制作的虚拟数据和代码:
import pandas as pd
from datetime import datetime
Item = pd.DataFrame({"ID":["A1","A1","A2","A2","A3","B1"],"DATE":["2021-07-05","2021-08-01","2021-02-02","2021-02-03","2021-01-01","2021-10-12"]})
Ver = pd.DataFrame({"ver_date" : ["2021-01-01","2021-07-07","2021-09-09"],"version":["1.1","1.2","1.3"]})
for id,dat in zip(Item["ID"],Item["DATE"]):
dat2 = datetime.strptime(dat,'%Y-%m-%d')
for dtc,ver in zip(Ver["ver_date"],Ver["version"]):
dtc = datetime.strptime(dtc,'%Y-%m-%d')
if dat2 >= dtc:
Item.loc[(Item.ID == id) & (Item.DATE == dat),"VER"] = ver
continue
else:
pass
所以我尝试的是这段代码。实际上这段代码有效,但我认为它效率不高,因为它在大约 1~2 分钟内给了我一个结果。 (200 个项目)。
您可以使用 merge_asof
。它按关键距离合并。默认情况下,它使用“向后”搜索,选择 Ver
中“ver_date”小于或等于 Item
的“日期”的最后一行(即您的 if-else 条件正在检查什么)。
它还希望对键进行合并以进行排序;所以您可以先将日期列转换为日期时间对象,然后按它们对 DataFrames 进行排序:
Item['DATE'] = pd.to_datetime(Item['DATE'])
Ver['ver_date'] = pd.to_datetime(Ver['ver_date'])
out = (pd.merge_asof(Item.sort_values(by='DATE'),
Ver.sort_values(by='ver_date'),
left_on='DATE', right_on='ver_date')
.drop(columns='ver_date')
.sort_values(by='ID')
.rename(columns={'version':'VER'}))
输出:
ID DATE VER
3 A1 2021-07-05 1.1
4 A1 2021-08-01 1.2
1 A2 2021-02-02 1.1
2 A2 2021-02-03 1.1
0 A3 2021-01-01 1.1
5 B1 2021-10-12 1.3
我试图制作一个代码来输入项目的版本。 有两个数据框,一个是项目,一个是版本信息。
这是我制作的虚拟数据和代码:
import pandas as pd
from datetime import datetime
Item = pd.DataFrame({"ID":["A1","A1","A2","A2","A3","B1"],"DATE":["2021-07-05","2021-08-01","2021-02-02","2021-02-03","2021-01-01","2021-10-12"]})
Ver = pd.DataFrame({"ver_date" : ["2021-01-01","2021-07-07","2021-09-09"],"version":["1.1","1.2","1.3"]})
for id,dat in zip(Item["ID"],Item["DATE"]):
dat2 = datetime.strptime(dat,'%Y-%m-%d')
for dtc,ver in zip(Ver["ver_date"],Ver["version"]):
dtc = datetime.strptime(dtc,'%Y-%m-%d')
if dat2 >= dtc:
Item.loc[(Item.ID == id) & (Item.DATE == dat),"VER"] = ver
continue
else:
pass
所以我尝试的是这段代码。实际上这段代码有效,但我认为它效率不高,因为它在大约 1~2 分钟内给了我一个结果。 (200 个项目)。
您可以使用 merge_asof
。它按关键距离合并。默认情况下,它使用“向后”搜索,选择 Ver
中“ver_date”小于或等于 Item
的“日期”的最后一行(即您的 if-else 条件正在检查什么)。
它还希望对键进行合并以进行排序;所以您可以先将日期列转换为日期时间对象,然后按它们对 DataFrames 进行排序:
Item['DATE'] = pd.to_datetime(Item['DATE'])
Ver['ver_date'] = pd.to_datetime(Ver['ver_date'])
out = (pd.merge_asof(Item.sort_values(by='DATE'),
Ver.sort_values(by='ver_date'),
left_on='DATE', right_on='ver_date')
.drop(columns='ver_date')
.sort_values(by='ID')
.rename(columns={'version':'VER'}))
输出:
ID DATE VER
3 A1 2021-07-05 1.1
4 A1 2021-08-01 1.2
1 A2 2021-02-02 1.1
2 A2 2021-02-03 1.1
0 A3 2021-01-01 1.1
5 B1 2021-10-12 1.3