Python 数据帧多索引上的替换操作

Python 数据帧多索引上的替换操作,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

我有两个数据帧,试图用另一个子串替换多索引的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'

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如果你决定使用这个答案,你可以接受这个答案。根据,您可以随时更改您的接受。您是对的,Think
str.replace
无法对索引进行操作。这应该是公认的答案@user2560244@user2560244如果你决定使用这个答案,你可以接受这个答案。根据,您可以随时更改您的接受。这里有一个循环。但更好。我能理解的唯一解决办法;-)这里有一个循环。但更好。我能理解的唯一解决办法;-)