我正在尝试将df2 ['values']列中的值分配给df1 ['values']列中。但是,仅在以下情况下才应分配值:
到目前为止,我拥有此代码,该代码可以工作,但是效率不高,因为处理两个df(df1大约有70万行)需要花两天的时间。
for i in df1.category.unique():
for j in df2.category.unique():
if i == j: # matching categories
for ia, ra in df1.loc[df1['category'] == i].iterrows():
for ib, rb in df2.loc[df2['category'] == j].iterrows():
if df1['date'][ia] in df2['date_range'][ib]:
df1.loc[ia, 'values'] = rb['values']
break
我读到我在处理数据帧时应尽量避免使用for循环。列表理解很棒,但是由于我还没有很多经验,所以我难以编写更复杂的代码。
如何更有效地遍历此问题?在带条件的数据帧上进行迭代时,我应考虑哪些基本的关键方面?
上面的代码趋向于跳过一些行或错误地分配它们,因此我之后需要进行清理。最大的问题是它真的很慢。
谢谢。
一些df1见解:
df1.head()
date category
0 2015-01-07 f2
1 2015-01-26 f2
2 2015-01-26 f2
3 2015-04-08 f2
4 2015-04-10 f2
一些df2见解:
df2.date_range[0]
DatetimeIndex(['2011-11-02', '2011-11-03', '2011-11-04', '2011-11-05',
'2011-11-06', '2011-11-07', '2011-11-08', '2011-11-09',
'2011-11-10', '2011-11-11', '2011-11-12', '2011-11-13',
'2011-11-14', '2011-11-15', '2011-11-16', '2011-11-17',
'2011-11-18'],
dtype='datetime64[ns]', freq='D')
df2其他两列:
df2[['values','category']].head()
values category
0 01 f1
1 02 f1
2 2.1 f1
3 2.2 f1
4 03 f1
答案 0 :(得分:0)
编辑:更正了错误代码,并添加了注释中的OP输入
好的,因此,如果要加入类似类别的数据框,可以merge
进行使用:
import pandas as pd
df3 = df1.merge(df2, on = "category")
接下来,由于date
是一个时间戳,并且根据OP的注释,“ date_range”实际上是从两列生成的,因此我们使用:
mask = (df3["startdate"] <= df3["date"]) & (df3["date"] <= df3["enddate"])
subset = df3.loc[mask]
现在,我们回到df1
并在公共日期合并,同时保留df1
中的所有值。这将为先前合并中与NaN
不匹配的子集值创建df1
。
因此,我们将df1["values"]
设置为其中公共条目不是NaN
,否则将其保留。
common_dates = df1.merge(subset, on = "date", how= "left") # keeping df1 values
df1["values"] = np.where(common_dates["values_y"].notna(),
common_dates["values_y"], df1["values"])
N.B:如果与日期范围匹配的多个df1["date"]
,则必须删除一些值,否则重复的内容会弄乱解释。