我有两个数据框,我试图将多索引的level1上的子字符串替换为另一个子字符串但是这会失败
例如,我有一个数据帧df
Index0 Index1 0 1 2
A BX .2 .3 .9
CX .34 .55 .54
D EX .34 .44 .32
FX .43. .88. .06
我正在尝试用 Y 替换 Index1 子串 X ,以便我的结果
看起来如下
Index0 Index1 0 1 2
A BY .2 .3 .9
CY .34 .55 .54
D EY .34 .44 .32
FY .43. .88. .06
我正在使用以下功能
df.replace('X','Y')
然而我收到以下错误
AttributeError Traceback (most recent call last)
<ipython-input-56-fc7014a2d950> in <module>()
8
9
---> 10 df.replace('X','Y')
AttributeError: 'MultiIndex' object has no attribute 'replace'
答案 0 :(得分:2)
@cᴏʟᴅsᴘᴇᴇᴅ改进了我的回答,所以我会在这里留下一个较慢的替补......
import numpy as np
df = pd.DataFrame(np.random.randn(4,3),
index=[list('aabb'), [n + 'X' for n in list('abcd')]])
以下是使用reset_index
的替代方法。如果您想要替换多个列,这将适用。诀窍是您不能在索引上使用replace
,因此您必须“将其带入”DataFrame。
new = (df.reset_index()
.select_dtypes(include=['object'])
.apply(lambda col: col.str.replace('X', 'Y')))
df.index = pd.MultiIndex.from_tuples(new.values.tolist())
答案 1 :(得分:2)
你做的比你需要的多。
df
0 1 2
Index0 Index1
A BX .2 .3 0.90
CX .34 .55 0.54
D EX .34 .44 0.32
FX .43. .88. 0.06
使用pd.MultiIndex.from_arrays
,您可以一步完成。
df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
df.index.levels[1].str.replace('X', 'Y')])
df
0 1 2
Index0 Index1
A BY .2 .3 0.90
CY .34 .55 0.54
D EY .34 .44 0.32
FY .43. .88. 0.06
<强>性能强>
%%timeit
new = (df.reset_index()
.select_dtypes(include=['object'])
.apply(lambda col: col.str.replace('X', 'Y')))
df.index = pd.MultiIndex.from_tuples(new.values.tolist())
10 loops, best of 3: 93.5 ms per loop
对于一个微小的数据帧,几乎100ms
。对比:
%%timeit
df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
df.index.levels[1].str.replace('X', 'Y')])
1000 loops, best of 3: 934 µs per loop
答案 2 :(得分:2)
或试试这个
df.index=pd.MultiIndex.from_tuples([(x[0], x[1].replace('X', 'Y')) for x in df.index])
df
Out[304]:
0 1 2
a aY -0.696181 -1.929523 -1.903956
bY 0.071061 -0.594185 -2.005251
b cY -0.097761 0.093667 1.780550
dY 0.127887 1.534395 0.352351