使用from_product()删除多级索引时报Key length超出索引深度错误
多级索引DataFrame删除指定行报错问题解决
问题背景
现有二级多级索引DataFrame:
close volume tickerId timestamp TSLA 2022-08-16 16:06:36 931.50 300.0 2022-08-16 16:06:37 931.69 1000.0 2022-08-16 16:06:38 931.69 200.0 2022-08-16 16:06:39 931.69 200.0 AAPL 2022-08-16 16:06:37 173.17 100.0
需求:删除TSLA对应的2022-08-16 16:06:36、2022-08-16 16:06:37、2022-08-16 16:06:38三条数据,保留AAPL的所有数据。已知待删除时间戳列表:
timestamp_list = [pd.Timestamp('2022-08-16 16:06:36'), pd.Timestamp('2022-08-16 16:06:37'), pd.Timestamp('2022-08-16 16:06:38')]
执行以下代码时出现报错:
multiindex = pd.MultiIndex.from_product([['TSLA'], timestamp_list]) df.drop(pd.MultiIndex.from_product(multiindex),axis=0, inplace=True)
报错信息:
File "/usr/local/lib/python3.9/site-packages/pandas/core/frame.py", line 4901, in drop return super().drop( File "/usr/local/lib/python3.9/site-packages/pandas/core/generic.py", line 4150, in drop obj = obj._drop_axis(labels, axis, level=level, errors=errors) File "/usr/local/lib/python3.9/site-packages/pandas/core/generic.py", line 4185, in _drop_axis new_axis = axis.drop(labels, errors=errors) File "/usr/local/lib/python3.9/site-packages/pandas/core/indexes/multi.py", line 2201, in drop loc = self.get_loc(level_codes) File "/usr/local/lib/python3.9/site-packages/pandas/core/indexes/multi.py", line 2927, in get_loc raise KeyError( KeyError: 'Key length (3) exceeds index depth (2)'
错误原因
你重复调用了pd.MultiIndex.from_product():
- 第一次调用已经生成了符合需求的二级MultiIndex(
['TSLA']和时间戳列表的笛卡尔积,每个索引元素是长度为2的元组); - 但在
df.drop()中再次将这个二级MultiIndex传入from_product,导致生成了三级索引(原二级索引的每个元组被拆解后做笛卡尔积,最终索引元素长度为3); - 而你的DataFrame只有二级索引,因此触发"Key length (3) exceeds index depth (2)"的报错。这个问题和timestamp是datetime类型无关,只是换成整数时巧合未触发该错误逻辑。
正确解法
方法1:直接传入生成好的二级MultiIndex
import pandas as pd # 生成要删除的二级索引组合 multiindex = pd.MultiIndex.from_product([['TSLA'], timestamp_list]) # 直接传入该MultiIndex,无需再次调用from_product df.drop(multiindex, axis=0, inplace=True)
方法2:布尔索引(更直观)
通过布尔条件筛选保留的行,避免索引操作的误区:
# 保留:不是TSLA, 或者是TSLA但timestamp不在待删除列表中的行 df = df[~((df.index.get_level_values('tickerId') == 'TSLA') & (df.index.get_level_values('timestamp').isin(timestamp_list)))]
内容的提问来源于stack exchange,提问作者alexx0186
相关产品推荐
相关产品推荐

