17

DataFrame の列からいくつかの値を変更したいと思います。現時点では、元のマルチインデックスを介して select からビューdfを取得しています (変更すると変更されますdf)。

次に例を示します。

In [1]: arrays = [np.array(['bar', 'bar', 'baz', 'qux', 'qux', 'bar']),
                  np.array(['one', 'two', 'one', 'one', 'two', 'one']),
                  np.arange(0, 6, 1)]
In [2]: df = pd.DataFrame(randn(6, 3), index=arrays, columns=['A', 'B', 'C'])

In [3]: df
                  A         B         C
bar one 0 -0.088671  1.902021 -0.540959
    two 1  0.782919 -0.733581 -0.824522
baz one 2 -0.827128 -0.849712  0.072431
qux one 3 -0.328493  1.456945  0.587793
    two 4 -1.466625  0.720638  0.976438
bar one 5 -0.456558  1.163404  0.464295

のスライスをdfスカラー値に変更しようとしています。

In [4]: df.ix['bar', 'two', :]['A']
Out[4]:
1    0.782919
Name: A, dtype: float64

In [5]: df.ix['bar', 'two', :]['A'] = 9999
# df is unchanged

私は本当に列のいくつかの値を変更したいです(そして、インデックス付けはスカラー値ではなくベクトルを返すので、これはより理にかなっていると思います):

In [6]: df.ix['bar', 'one', :]['A'] = [999, 888]
# again df remains unchanged

私はパンダ0.11を使用しています。これを行う簡単な方法はありますか?

現在の解決策は、新しいものから df を再作成し、必要な値を変更することです。しかし、それはエレガントではなく、複雑なデータフレームでは非常に重くなる可能性があります. 私の意見では、問題はビューではなくコピーを返す .ix および .loc にあるはずです。

4

1 に答える 1

14

フレームをソートし、マルチインデックスのタプルを使用して選択/設定します

In [12]: df = pd.DataFrame(randn(6, 3), index=arrays, columns=['A', 'B', 'C'])

In [13]: df
Out[13]: 
                  A         B         C
bar one 0 -0.694240  0.725163  0.131891
    two 1 -0.729186  0.244860  0.530870
baz one 2  0.757816  1.129989  0.893080
qux one 3 -2.275694  0.680023 -1.054816
    two 4  0.291889 -0.409024 -0.307302
bar one 5  1.697974 -1.828872 -1.004187

In [14]: df = df.sortlevel(0)

In [15]: df
Out[15]: 
                  A         B         C
bar one 0 -0.694240  0.725163  0.131891
        5  1.697974 -1.828872 -1.004187
    two 1 -0.729186  0.244860  0.530870
baz one 2  0.757816  1.129989  0.893080
qux one 3 -2.275694  0.680023 -1.054816
    two 4  0.291889 -0.409024 -0.307302

In [16]: df.loc[('bar','two'),'A'] = 9999

In [17]: df
Out[17]: 
                     A         B         C
bar one 0    -0.694240  0.725163  0.131891
        5     1.697974 -1.828872 -1.004187
    two 1  9999.000000  0.244860  0.530870
baz one 2     0.757816  1.129989  0.893080
qux one 3    -2.275694  0.680023 -1.054816
    two 4     0.291889 -0.409024 -0.307302

完全なインデックスを指定すると、ソートなしで実行することもできます。

In [23]: df.loc[('bar','two',1),'A'] = 999

In [24]: df
Out[24]: 
                    A         B         C
bar one 0   -0.113216  0.878715 -0.183941
    two 1  999.000000 -1.405693  0.253388
baz one 2    0.441543  0.470768  1.155103
qux one 3   -0.008763  0.917800 -0.699279
    two 4    0.061586  0.537913  0.380175
bar one 5    0.857231  1.144246 -2.369694

ソート深度を確認するには

In [27]: df.index.lexsort_depth
Out[27]: 0

In [28]: df.sortlevel(0).index.lexsort_depth
Out[28]: 3

質問の最後の部分、リストでの割り当て (置き換えようとしているのと同じ数の要素が必要であることに注意してください)。これを機能させるには、これをソートする必要があります。

In [12]: df.loc[('bar','one'),'A'] = [999,888]

In [13]: df
Out[13]: 
                    A         B         C
bar one 0  999.000000 -0.645641  0.369443
        5  888.000000 -0.990632 -0.577401
    two 1   -1.071410  2.308711  2.018476
baz one 2    1.211887  1.516925  0.064023
qux one 3   -0.862670 -0.770585 -0.843773
    two 4   -0.644855 -1.431962  0.232528
于 2013-05-30T11:27:18.597 に答える