2014-09-11 38 views
12

örneğin Python 2.7.5 ile pandas sürümü 0.14.1 kullanıyorum ve üç sütunlu bir veri çerçevesi vardır:Sadece bir satır kullanarak pandalar veri karesinde seçilen satırlar için sütun değerlerini değiştirmek için doğru sözdizimi nedir?

 L  R VALUE 
0 left right  -1 
1 right left  1 
2 left right  -1 
3 right left  1 
4 left right  -1 
5 right left  1 
: şöyle bir veri çerçevesi içinde

import pandas as pd 

d = {'L': ['left', 'right', 'left', 'right', 'left', 'right'], 
    'R': ['right', 'left', 'right', 'left', 'right', 'left'], 
    'VALUE': [-1, 1, -1, 1, -1, 1]} 
df = pd.DataFrame(d) 

idx = (df['VALUE'] == 1) 

sonuçları

VALUE == 1'un bulunduğu satırlarda, sol ve sağ sütunların içeriğini değiştirmek istiyorum, böylece "sol" değerlerin tümü "L" sütununun altına ve "sağ" değerlerin altında kalıyor. "R" sütunu.

Kolayca şöyle geçici bir değişken kullanarak, sadece üç tane daha hatlarında yapabilirsiniz, zaten olması yukarıda idx tanımlı değişkenlere:

tmp = df.loc[idx,'L'] 
df.loc[idx,'L'] = df.loc[idx,'R'] 
df.loc[idx,'R'] = tmp 

ancak bu benim için gerçekten aksak ve inelegant sözdizimi gibi görünüyor; kesinlikle pandalar daha özlü bir şeyi destekliyor mu?

In [2]: print(df.loc[idx,['R','L']]) 
     R  L 
1 left right 
3 left right 
5 left right 

Bu aynı takas uygulamak mümkün olması gerektiğini bana gösteriyor: Ben veri çerçevesi .loc öznitelik için girişteki sütun sırasını takas eğer, o zaman ben şu takas çıkış olsun fark ettik yukarıdaki gibi, sadece aşağıdaki tek satırını kullanarak:

df.loc[idx,['L','R']] = df.loc[idx,['R','L']] 

Ancak aslında bu çalıştığınızda hiçbir şey olmuyor - sütunlar unswapped kalır. Pandalar, sütunları atama bildiriminin sağ tarafında yanlış sıraya koyduğumu otomatik olarak algılar ve sorun için otomatik olarak düzeltir. Takasın gereksiz geçici değişkenler oluşturmadan uygulanabilmesi için pandalar atamalarında bu "sütun düzenini otomatik düzeltme" özelliğini devre dışı bırakmamın bir yolu var mı? Sütun adlarına hizalama önlemek olabilir

+0

Eğer dataframe.eval baktın mı? Onlar pandalar docs örnek var: >>> df = DataFrame (randn (10, 2), sütunlar = liste ('ab')) >>> df.eval ('a + b') >>> df. eval ('c = a + b') – Rainy

+0

Merak eden herkes için bir takip sorusu gönderdim: http://stackoverflow.com/questions/25811529/setting-values-on-a-subset-of-rows -ekeksleme-boolean ayarı – JohnE

cevap

16

Tek yön .values aracılığıyla altta yatan diziye aşağı düşmesi olacaktır:

In [33]: df 
Out[33]: 
     L  R VALUE 
0 left right  -1 
1 right left  1 
2 left right  -1 
3 right left  1 
4 left right  -1 
5 right left  1 

In [34]: df.loc[idx,['L','R']] = df.loc[idx,['R','L']].values 

In [35]: df 
Out[35]: 
     L  R VALUE 
0 left right  -1 
1 left right  1 
2 left right  -1 
3 left right  1 
4 left right  -1 
5 left right  1 
+0

Bu, yalnızca _idx_ dizisi dtype _bool_ ise düzgün çalışıyor gibi görünüyor. Diziniz, True/False yerine 0/1 değerine sahipse, 'idx.astype (bool)' kullanarak dtype _bool_ dizinine dönüştürün. – ashimashi

3

Burada dikkat edilmesi gereken önemli şey otomatik satır ve sütun kullanarak hizalamak için bu pandalar girişimleri olduğunu dizin ve sütun adları. Bu nedenle, bir şekilde pandaların buradaki sütun adlarını görmezden gelmeleri gerektiğini söylemelisiniz. Bir yol, bir sayı dizisine dönüştürerek @DSM'nin yaptığı gibidir. Diğer bir yolu sütunları yeniden adlandırmak etmektir: Ayrıca np.select ve df.where i ile yapabilirsiniz

>>> df.loc[idx] = df.loc[idx].rename(columns={'R':'L','L':'R'}) 

     L  R VALUE 
0 left right  -1 
1 left right  1 
2 left right  -1 
3 left right  1 
4 left right  -1 
5 left right  1 
+0

Yanıtınız için teşekkür ederiz; İlk cevap verdiğimden beri DSM'ye "kabul edilmiş cevap" statüsü verdim, ama cevabınızı da oldukça faydalı buldum (ve bu yüzden onu destekledim!). Btw, bence ilk metodunuzda bir yazım hatası olabilir; benim sistemimde pandalar 0.14.1 ve Python 2.7.5 ile çalışır, eğer zip yerine bir çağrı eklerse çalışır; yani, df.ix [idx, ['L', 'R']] = zip (df.ix [idx, 'R'], df.ix [idx, 'L']) '. İkinci yöntem gayet iyi çalışıyor, bunun için teşekkürler! 3. yöntem için, problemin sağ taraftaki df [['R', 'L']] 'nin 6 satır uzunluğunda olduğunu, df.loc [idx, [' L ',' R] olduğunu düşünüyorum. ']] 'sadece 3 satırdır. – stachyra

+0

Geri bildirim için teşekkürler. Yöntem 1, fermuar olmadan benim için iyi çalışıyor (ve ayrıca zip eklerseniz). Neden farklı sonuçlar aldığımız hakkında bir fikrim yok. Ben panda 14.1 ve python 2.7.7 (anakonda dağılımı) var. Pencerelerin altında koşmak 7. – JohnE

1

.E

Seçenek 1: np.select

df[['L','R']] = pd.np.select(df['VALUE'] == 1, df[['R','L']].values, df[['L','R']].values) 

Seçenek 2: df.where

df[['L','R']] = df[['R','L']].where(df['VALUE'] == 1, df[['L','R']].values) 

Seçenek 3: df.mask

df[['L','R']] = df[['L','R']].mask(df['VALUE'] == 1, df[['R','L']].values) 

Çıktı:

L  R VALUE 
0 left right  -1 
1 left right  1 
2 left right  -1 
3 left right  1 
4 left right  -1 
5 left right  1 
İlgili konular