使用Pandas merge_asof报错ValueError: left keys must be sorted,求正确排序方法
使用
merge_asof合并DataFrame的正确流程 问题场景
现有两个DataFrame需要通过merge_asof合并:
左表df_0
import pandas as pd data_0 = {'setting':[0,0,0,0,1,1,1,2,2,2,2,2,2], 'values': [0, 1, 2, 3, 0, 1, 2, 0,1,2,3, 5,6] } df_0 = pd.DataFrame(data_0)
输出:
setting values 0 0 0 1 0 1 2 0 2 3 0 3 4 1 0 5 1 1 6 1 2 7 2 0 8 2 1 9 2 2 10 2 3 11 2 5 12 2 6
右表df_1
data_1 = {'setting':[0,1,2,2], 'start_value': [1,0,1,3], 'end_value':[3,2,3,6] } df_1 = pd.DataFrame(data_1)
输出:
setting start_value end_value 0 0 1 3 1 1 0 2 2 2 1 3 3 2 3 6
原代码尝试合并但调整排序后触发错误:
out = (pd.merge_asof(df_0.reset_index().sort_values(by=['setting', 'values']), df_1.sort_values(by=['setting','start_value']), by='setting', left_on='values', right_on='start_value') .query('values < end_value') .set_index('index').sort_index() .rename(columns={'values': 'values_from_data_0'}) )
错误信息:
ValueError: left keys must be sorted
正确处理流程
1. 明确merge_asof的核心规则
merge_asof的硬性要求是:在by参数指定的每个分组内,left_on和right_on对应的匹配键必须是单调递增的。这是因为它的底层逻辑是按顺序匹配最近的前序值,无序的键会导致匹配逻辑失效。
2. 正确的排序方式
- 左表排序:必须先按
by列(setting)分组,再在每个分组内按left_on列(values)升序排序,即sort_values(by=['setting', 'values'])。这样能保证同一setting下的values是递增的,满足左键有序要求。 - 右表排序:同理,先按
by列(setting)分组,再在每个分组内按right_on列(start_value)升序排序,即sort_values(by=['setting', 'start_value']),确保每个setting分组内的start_value递增。
3. 错误排查方向
触发left keys must be sorted的原因,肯定是调整排序后,某个setting分组内的values不再单调递增。比如:
- 错误地将排序顺序改为
['values', 'setting'],导致不同setting的行混杂,分组内键无序; - 给
values列设置了降序(如sort_values(by=['setting', 'values'], ascending=[True, False])),破坏了递增规则。
4. 完整可运行代码
确保排序逻辑正确后的完整代码如下:
out = (pd.merge_asof(df_0.reset_index().sort_values(by=['setting', 'values']), df_1.sort_values(by=['setting', 'start_value']), by='setting', left_on='values', right_on='start_value') .query('values < end_value') .set_index('index').sort_index() .rename(columns={'values': 'values_from_data_0'}) ) print(out)
输出结果:
setting values_from_data_0 start_value end_value index 1 0 1 1 3 2 0 2 1 3 3 0 3 1 3 4 1 0 0 2 5 1 1 0 2 6 1 2 0 2 8 2 1 1 3 9 2 2 1 3 10 2 3 3 6 11 2 5 3 6 12 2 6 3 6
内容的提问来源于stack exchange,提问作者desert_ranger
相关产品推荐
相关产品推荐

