2017-09-07 1 views
-1
私は別の部分文字列とマルチインデックスのLEVEL1に部分文字列を置き換えるためにしようとしている2つのデータフレームを持っているが、これは

は、データフレームの操作を元に戻しマルチインデックス

を失敗例えば、私は

Index0 Index1 0  1  2 
A  BX  .2 .3 .9  
     CX  .34 .55 .54   

D  EX  .34 .44 .32 
     FX  .43. .88. .06 

I DFのデータフレームを持って

置き換えをしようとしていますYによって X サブ INDEX1私の結果は
がlに見えるようにすることを

Index0 Index1 0  1  2 
A  BY  .2 .3 .9  
     CY  .34 .55 .54   

D  EY  .34 .44 .32 
     FY  .43. .88. .06 

を次のように私は遅く、代替を残しますので、IKEは私が

df.replace('X','Y') 

は、しかし、私はcᴏʟᴅsᴘᴇᴇᴅ@

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

をお試しくださいDFを作成するためのコードを追加してください。実際、 'df'はインデックスのように見えます。 –

+0

dfはデータフレームです。 Index0とIndex1はdfデータフレームのインデックスです。 で – user2560244

+0

はAttributeErrorトレースバック(最新のコール最後) () 9 ---> 10 df.replace( 'X'、 'Y') はAttributeError: ' MultiIndex 'オブジェクトに属性' replace 'がありません – user2560244

答えて

2

が私の答えに向上し、次のエラーを取得する次の関数を使用していますここ...

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()) 
+0

良いアプローチ - 私は 'reset_index'を使用してインデックスを編集可能なデータフレーム列にプッシュしていました。そして、' set_index'を使ってそれらの値をインデックスに戻しました。これはあまり侵襲的ではありません。よりエレガント。 – jdg

+0

私は単純な交換を行うだけのシリーズを使用することがこれを行うための最良の方法だとは思わない。 –

+0

私の名前の誤植は目的にかなっていますか? :p –

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を使用すると、これを1ステップで実行できます。

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 
+0

woww ...これは素晴らしいです。ありがとう – user2560244

+0

あなたは正しいです、 'str.replace'はインデックス上で動作できないと考えました。これは受け入れられた答えでなければなりません@ user2560244 –

+0

これは私の頭の中で何ですか! :) – Wen

1

またはこの

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 
+1

ここにループがあります。しかし、まだ、より良い。 –

関連する問題