2013-05-30 27 views
16

DataFrame'mdeki bir sütundan bazı değerleri değiştirmek istiyorum. Şu anda, df (df) 'un çoklu indeksi üzerinden seçerek görünüm görünümüm var (ve değiştirmeyi df değiştirir).MultiIndex DataFrame'den dilim için yeni değerler atama

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 

bir skaler değere df bir dilim değiştirmeye çalışın: İşte

bir örnek

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 
Gerçekten sütunda birkaç değerlerini değiştirmek istediğiniz

(ve beri indeksleme bir vektör döndürür, bir skaler değer değil, bence bu daha mantıklı olur):

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

0.13 panda kullanıyorum. Bunu yapmanın basit bir yolu var mı?

Geçerli çözüm, df'yi yenisinden yeniden oluşturmak ve istediğim değerleri değiştirmek. Ancak bu zarif değil ve karmaşık veri karelerinde çok ağır olabilir. Benim düşünceme göre sorun .ix ve .loc bir görünüm ama bir kopyasını döndüren değil gelmelidir. Eğer, örneğin tam dizini belirtirseniz

+0

neden sıralanır? En azından açıklayabilir misin? – HadiM

+0

+1, kafa karıştırıcı bir konuya mükemmel bir soru. Düşünebildiğim tek şey, açıklayıcı olmamakla ilgili başlıktan dolayı indirgenmiş olması mı? (ama kim bilir!) –

+1

Başlık için üzgünüm ama ingilizce ana dili konuşmacısı değilim ve konu biraz karmaşık, bu yüzden iyi bir tane bulmak zor :-) Bana bir başlık göndermek istiyorsanız, akımı değiştirebilirim bir. – HadiM

cevap

10

Sıralama çerçeve, daha sonra da sıralama out yapabilir çoklu endeks

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 

için bir demet kullanarak/grubu seçin

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 

, (Değiştirmeye çalıştığınız gibi unsurların aynı sayıda gerektiğini unutmayın) bir listesini atama, sıralama derinliği

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

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

sorunuzun son kısmı kontrol etmek ve bu iş için

+0

Yani, hepsi sıralama ... Tamam, gelecekte bunu kullanacağım. Hile için teşekkürler! – HadiM

+1

Evet, bu arkadaşınız olsun: http://pandas.pydata.org/pandas-docs/dev/indexing.html#the-need-for-sortedness – Jeff