You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:45:57