Python 熊猫在多索引上设置_级别:级别值必须唯一
给定一个数据帧Python 熊猫在多索引上设置_级别:级别值必须唯一,python,pandas,dataframe,indexing,multi-index,Python,Pandas,Dataframe,Indexing,Multi Index,给定一个数据帧df Value Category Pool Class A 1.0 1.0 1 9.0 2 B 1.0 1.0 3 C 1.0 1.0 4 5.0 5 我想将级别池和类转换为不带重置索引的整数(见下文) 我尝试使用get\u level\u值和set\u level
df
Value
Category Pool Class
A 1.0 1.0 1
9.0 2
B 1.0 1.0 3
C 1.0 1.0 4
5.0 5
我想将级别池
和类
转换为不带重置索引的整数(见下文)
我尝试使用get\u level\u值
和set\u levels
的组合,就像这样
for c in ['Pool', 'Class']:
df.index.set_levels(df.index.get_level_values(c).astype(int), level=c, inplace=True)
然而,这增加了
ValueError: Level values must be unique: [1, 1, 1, 1, 1] on level 1
为了了解发生了什么,我还尝试使用verify\u integrity=False
。然后
df.index.set_levels(df.index.get_level_values('Class').astype(int),
level='Class', verify_integrity=False, inplace=True)
产生
Value
Category Pool Class
A 1.0 1 1
1 2
B 1.0 1 3
C 1.0 1 4
9 5
而我的目标是获得
Value
Category Pool Class
A 1.0 1 1
9 2
B 1.0 1 3
C 1.0 1 4
5 5
如何恰当地实现这一点?链接get\u level\u value
和set\u levels
是否是正确的方法?为什么使用astype
转换后,pandas
无法正确设置级别
我想你可以使用reset\u index
和set\u index
但是使用set\u levels
方法有什么好处呢
d = {'Category': str, 'Pool': int, 'Class': int}
df.reset_index(drop=False, inplace=True)
for k, v in d.items():
df[k] = df[k].astype(v)
df.set_index(list(d.keys()), inplace=True)
您可以通过pd.MultiIndex.levels
直接访问索引级别,并将其馈送至:
以下函数可用作获取级别值的补充:
def set_level_values(midx, level, values):
full_levels = list(zip(*midx.values))
names = midx.names
if isinstance(level, str):
if level not in names:
raise ValueError(f'No level {level} in MultiIndex')
level = names.index(level)
if len(full_levels[level]) != len(values):
raise ValueError('Values must be of the same size as original level')
full_levels[level] = values
return pd.MultiIndex.from_arrays(full_levels, names=names)
使用此功能,原始问题的解决方案为:
for c in ['Pool', 'Class']:
df.index = set_level_values(df.index, level=c, values=df.index.get_level_values(c).astype(int))
谢谢如何按名称引用级别?事实上,我有一个dict
级别名称和类型,我想用于转换。另外,上面的ValueError
的原因是什么?levels
与get\u level\u values
不同,前者是set\u levels
所期望的<代码>级别
获取唯一索引,获取级别值
获取每个索引。它们根本不同,你自己来测试一下。这也可能是您获取ValueError
@jpp的原因。是否有某种set\u level\u values
方法可以补充get\u level\u values
?@Eran,据我所知,这是不存在的。我只看到set\u levels
。
for c in ['Pool', 'Class']:
df.index = set_level_values(df.index, level=c, values=df.index.get_level_values(c).astype(int))