提问人:thefrollickingnerd 提问时间:3/7/2023 最后编辑:cottontailthefrollickingnerd 更新时间:3/7/2023 访问量:39
使用条件从不同 DataFrame 获取聚合到当前 DataFrame
Get aggregates from different Dataframe to current Dataframe with conditions
问:
我有一个收获数据框和一个天气数据框。 我想获得所有区块在收获前 x 个月高于温度阈值的天数。 请注意,收获数据帧包含多个年份,并且帧之间的 id 不是 1-1,即收获 df 中的 2 个块可以共享一个与天气帧中的位置相对应的 ID。
我当前的(工作)代码如下,但它非常慢,大约几分钟。我想加快速度,但不清楚如何。
def days_above_thresh(x, weather_df):
return weather_df.loc[
(weather_df["id"]==x.id) & \
(weather_df["day"]>=x['harvest_date']-DateOffset(months=2)) & \
(weather_df["day"]<=x['harvest_date']) & \
(weather_df["temperature_max"]>30),
"temperature_max"].count()
harvest_df["days_above_30"] = harvest_df.apply(days_above_thresh , args=(weather_df,), axis=1)
数据帧将如下所示 -
weather_df
id day temperature_max
1 2020-01-01 30
1 2020-01-02 32
1 2020-01-03 28
1 2020-01-04 25
.
.
.
2 2020-01-01 10
2 2020-01-02 15
2 2020-01-03 17
2 2020-01-04 12
.
.
.
harvest_df
id farm_id harvest_date
1 87 2020-01-02
1 86 2020-01-03
2 13 2020-01-30
答:
1赞
cottontail
3/7/2023
#1
这可以通过合并两个帧来加快速度,使用布尔掩码(在您定义的函数中构造)过滤生成的帧并调用结果。id
groupby.size
如果您的帧很大(但不要太大),这将大大减少运行时间(如果是 10k 行,则将运行时间从 13.5 秒减少到 15 毫秒)。但是,如果太大(可能是数百万行),因为它会创建更大的帧,因此可能会遇到内存问题。harvest_df
harvest_df
此外,由于某种原因未进行优化;但是,是的,因此更换它可以进一步提高速度。pd.DateOffset
np.timedelta64
tmp = harvest_df.reset_index().merge(weather_df[['id', 'day', 'temperature_max']], on='id', how='left')
msk = tmp['day'].between(tmp['harvest_date'].sub(np.timedelta(2, 'M')).dt.floor('D'), tmp['harvest_date']) & tmp['temperature_max'].gt(30)
harvest_df["days_above_30"] = tmp[msk].groupby('index').size().reindex(harvest_df.index, fill_value=0)
也可以写成一行:
harvest_df["days_above_30"] = (
harvest_df.reset_index().merge(weather_df[['id', 'day', 'temperature_max']], on='id', how='left')
.assign(two_month_prior=lambda x: x['harvest_date'].sub(np.timedelta64(2, 'M')).dt.floor('D'))
.query("two_month_prior <= day <= harvest_date and temperature_max > 30")
.groupby('index').size()
.reindex(harvest_df.index, fill_value=0)
)
评论
0赞
thefrollickingnerd
3/7/2023
天气数据帧非常大(34k 行),收获 df 为 12k 行,因此这将创建一个巨大的数据帧。我认为这会导致内存问题。但是,这种选择仍然非常受欢迎。刚刚尝试过,内核崩溃了
0赞
cottontail
3/7/2023
@thefrollickingnerd 34k 行足够小,应该不会引起任何问题。
0赞
thefrollickingnerd
3/7/2023
对不起,我错过了一个零,天气 df 是 340k 行
评论