Python 数据帧多索引上的替换操作
我有两个数据帧,试图用另一个子串替换多索引的level1上的子串,但失败了 例如,我有一个数据帧dfPython 数据帧多索引上的替换操作,python,pandas,dataframe,replace,multi-index,Python,Pandas,Dataframe,Replace,Multi Index,我有两个数据帧,试图用另一个子串替换多索引的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替换Inde
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'
AttributeError回溯(最近一次调用)
在()
8.
9
--->10 df.替换('X','Y')
AttributeError:“多索引”对象没有属性“替换”
@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\u index
的替代方法。如果您想在多个列中替换,这将是适用的。诀窍在于不能在索引上使用replace
,因此必须将其“放入”数据帧
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())
@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\u index
的替代方法。如果您想在多个列中替换,这将是适用的。诀窍在于不能在索引上使用replace
,因此必须将其“放入”数据帧
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())
你做的比你需要的多
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
你做的比你需要的多
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
或者试试这个
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
或者试试这个
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
请添加创建df的代码。实际上,
df
看起来像一个Indexdf是一个数据帧。Index0和Index1是()8 9--->10 df.replace('X','Y')AttributeError中df dataframe.AttributeError回溯(最近一次调用)的索引:“多索引”对象没有属性“replace”Yes,我想用上面突出显示的另一个子字符串修改多索引子字符串,但我无法这样做,因此我的问题是。请添加创建df的代码。实际上,df
看起来像一个Indexdf是一个数据帧。Index0和Index1是()8 9--->10 df.replace('X','Y')AttributeError中df dataframe.AttributeError回溯(最近一次调用)的索引:“多索引”对象没有属性“replace”Yes,我想用上面突出显示的另一个子字符串修改多索引子字符串,但我无法这样做,因此我提出了我的问题。好方法-我使用了一个使用reset\u index
-将索引推到可编辑的数据框列中-然后使用set\u index
将这些值推回到索引中。这是侵入性较小的;更优雅。我不认为仅仅用一个系列来做一个简单的替换是最好的方法。@Coldspeed没有,但不是很吸引人??好方法-我在玩一个使用reset\u index
-将索引推到可编辑的数据框列中-然后使用set\u index
将这些值推回到索引中的方法。这是侵入性较小的;更优雅。我不认为仅仅用一个系列来做一个简单的替换是最好的方法。@Coldspeed不,但不是那么吸引人吗?你说得对,我想str.replace
不能对索引进行操作。这应该是公认的答案@user2560244@user2560244如果你决定使用这个答案,你可以接受这个答案。根据,您可以随时更改您的接受。您是对的,Thinkstr.replace
无法对索引进行操作。这应该是公认的答案@user2560244@user2560244如果你决定使用这个答案,你可以接受这个答案。根据,您可以随时更改您的接受。这里有一个循环。但更好。我能理解的唯一解决办法;-)这里有一个循环。但更好。我能理解的唯一解决办法;-)