2012-01-18 21 views
29

Bir csv dosyasından kullanılarak oluşturulan pandalarda bir veri çerçevem ​​var df. Veri çerçevesinin birkaç sütunu vardır ve sütunlardan biri tarafından indekslenir (her satırın, dizinleme için kullanılan bu sütun için benzersiz bir değere sahip olması benzersizdir.)python pandaları ile birden çok sütun arasında seçim yapmak?

Veri çerçevemdeki satırları bir "karmaşık" filtre birden çok sütuna uygulandı mı? Sütun colA örneğin 10'dan büyük olduğu kolayca dataframe dilim dışarı seçebilirsiniz: sütunlardan herhangi büyük olduğu df dilim seçin: Ne isterse

df_greater_than10 = df[df["colA"] > 10] 

Ama ne gibi bir filtre 10'dan mı?

Veya colA için değer 10'dan büyükse, colB değeri 5'ten az mı?

Bunlar pandalarda nasıl uygulanır? Teşekkürler.

cevap

36

Bu soruları mailing list numaralı telefondan oluşturmanızı öneririm, ancak her halükarda alttaki NumPy dizileriyle çalışan çok düşük düzeydeki bir ilişkidir. Örneğin, bu örnekte, diyelim 1.5 bir sütunundaki değer aşan satırları seçmek için

In [11]: df 
Out[11]: 
      A  B  C  D  
2000-01-03 -0.59885 -0.18141 -0.68828 -0.77572 
2000-01-04 0.83935 0.15993 0.95911 -1.12959 
2000-01-05 2.80215 -0.10858 -1.62114 -0.20170 
2000-01-06 0.71670 -0.26707 1.36029 1.74254 
2000-01-07 -0.45749 0.22750 0.46291 -0.58431 
2000-01-10 -0.78702 0.44006 -0.36881 -0.13884 
2000-01-11 0.79577 -0.09198 0.14119 0.02668 
2000-01-12 -0.32297 0.62332 1.93595 0.78024 
2000-01-13 1.74683 -1.57738 -0.02134 0.11596 
2000-01-14 -0.55613 0.92145 -0.22832 1.56631 
2000-01-17 -0.55233 -0.28859 -1.18190 -0.80723 
2000-01-18 0.73274 0.24387 0.88146 -0.94490 
2000-01-19 0.56644 -0.49321 1.17584 -0.17585 
2000-01-20 1.56441 0.62331 -0.26904 0.11952 
2000-01-21 0.61834 0.17463 -1.62439 0.99103 
2000-01-24 0.86378 -0.68111 -0.15788 -0.16670 
2000-01-25 -1.12230 -0.16128 1.20401 1.08945 
2000-01-26 -0.63115 0.76077 -0.92795 -2.17118 
2000-01-27 1.37620 -1.10618 -0.37411 0.73780 
2000-01-28 -1.40276 1.98372 1.47096 -1.38043 
2000-01-31 0.54769 0.44100 -0.52775 0.84497 
2000-02-01 0.12443 0.32880 -0.71361 1.31778 
2000-02-02 -0.28986 -0.63931 0.88333 -2.58943 
2000-02-03 0.54408 1.17928 -0.26795 -0.51681 
2000-02-04 -0.07068 -1.29168 -0.59877 -1.45639 
2000-02-07 -0.65483 -0.29584 -0.02722 0.31270 
2000-02-08 -0.18529 -0.18701 -0.59132 -1.15239 
2000-02-09 -2.28496 0.36352 1.11596 0.02293 
2000-02-10 0.51054 0.97249 1.74501 0.20525 
2000-02-11 0.10100 0.27722 0.65843 1.73591 

In [12]: df[(df.values > 1.5).any(1)] 
Out[12]: 
      A  B  C  D  
2000-01-05 2.8021 -0.1086 -1.62114 -0.2017 
2000-01-06 0.7167 -0.2671 1.36029 1.7425 
2000-01-12 -0.3230 0.6233 1.93595 0.7802 
2000-01-13 1.7468 -1.5774 -0.02134 0.1160 
2000-01-14 -0.5561 0.9215 -0.22832 1.5663 
2000-01-20 1.5644 0.6233 -0.26904 0.1195 
2000-01-28 -1.4028 1.9837 1.47096 -1.3804 
2000-02-10 0.5105 0.9725 1.74501 0.2052 
2000-02-11 0.1010 0.2772 0.65843 1.7359 

Çoklu koşullar & veya | kullanılarak kombine edilmesi (ve parantez!)

In [13]: df[(df['A'] > 1) | (df['B'] < -1)] 
Out[13]: 
      A  B  C  D  
2000-01-05 2.80215 -0.1086 -1.62114 -0.2017 
2000-01-13 1.74683 -1.5774 -0.02134 0.1160 
2000-01-20 1.56441 0.6233 -0.26904 0.1195 
2000-01-27 1.37620 -1.1062 -0.37411 0.7378 
2000-02-04 -0.07068 -1.2917 -0.59877 -1.4564 

Bu tür şeyleri daha kolay hale getirmek için bir çeşit sorgu API'sine sahip olmak isterim

+1

Tekrar teşekkürler. Mail listesiyle ilgili gelecek soruları yayınlayın. Ama şimdilik, bunu program aracılığıyla yapmak isteseydiniz? Sütun etiketlerinin bir listesi vardı ... bunu '|' içine nasıl alabilirdiniz? notasyonu? Örneğin. Eğer etiketler = ['A', 'B', 'C', ... '] ' – user248237dfsf

+0

Açıklığa kavuşturmak için:“ Herhangi bir (1) ”yaklaşımı, sizde, diğer Filtrelemek istemiyorum. Çok sayıda sütun olduğunu ve sadece herhangi birinin bir alt kümesine (alt kümenin etiketlerini biliyorsunuz) başvurmasını istediğinizi varsayalım. – user248237dfsf

5

Pandas'taki sözdizimini kısaltmak için en az birkaç yaklaşım vardır; yol (perhap) github projesine katılmaya çalışacağım ve bunu yapmak için zaman izinleri ve başka hiç kimse başlamadıysa).

bir yöntem biraz aşağıda verilmiştir sözdizimi kısaltmak için:

inds = df.apply(lambda x: x["A"]>10 and x["B"]<5, axis=1) 
print df[inds].to_string() 

tam Bunu çözmek için tek seçip SQL gibi bir şey inşa etmek gerekir nereye Pandalar içine hükümler. Bu hiç de önemsiz değil, ama bence bu işe yarayan bir bıçak Python operator yerleşik modülünü kullanmaktır. Bu, semboller yerine işlevler yerine daha büyük şeyler gibi davranmanıza olanak tanır. Yani yapabileceğini aşağıdadır:

import operator 
select_dict = { 
       "A":(operator.gt,10), 
       "B":(operator.lt,5)     
       } 

print pandas_select(df, select_dict).to_string() 

Sen hiç pandas_select daha argümanlar ya binanın tarafından daha da sözdizimi kısaltabilir:

def pandas_select(dataframe, select_dict): 

    inds = dataframe.apply(lambda x: reduce(lambda v1,v2: v1 and v2, 
          [elem[0](x[key], elem[1]) 
          for key,elem in select_dict.iteritems()]), axis=1) 
    return dataframe[inds] 

Sonra sizinki gibi bir test örneği, aşağıdaki yapmak olacaktır Farklı ortak mantıksal işleçleri otomatik olarak veya daha kısa adlarla ad alanına içe aktararak.

Yukarıdaki pandas_select işlevinin yalnızca mantıksal ve kısıtlama zincirleriyle çalıştığını unutmayın. Farklı mantıksal davranışlar elde etmek için onu değiştirmeniz gerekir. Ya da not ve DeMorgan yasalarını kullanın.

+0

Listem varsa ['Alice', 'Bob', 'Carl'] Listemde veri karelerinin ['A'] bulunduğu öğeleri seçmek için nasıl sözlük oluşturabilirim? –

+1

Liste a = ['Alice', 'Bob', 'Carl'] 'ise ve genel veri çerçevesi' df' olarak adlandırılırsa, bunu yapabilirsiniz: 'df [df.A.isin (a) ] 've ayarlanan üyelik koşulunun, 'A' sütun öğeleri için doğru olduğu satır indekslerini alt-seçecektir. Basit sözdizimi ile bu seçeneğe sahip olmak için mantıksal ifadeleri ifade etmek için yukarıda yaptığım mini alana özgü dili genişletmek muhtemelen rahatsız edici bir iş olacaktır. – ely

+0

belki de gelecek (pandalar 0.13) sorgu yöntemine bakınız: http://pandas.pydata.org/pandas-docs/dev/indexing.html?highlight=query#the-query-method-experimental ve ayrıca http : //stackoverflow.com/questions/18521037/pandas-iterative-filtering-a-dataframes-rows – RuiDC

1

Bu soru soruldu ve yanıtlandığı için Pandalara bir sorgulama özelliği eklendi. Aşağıda bir örnek verilmiştir. Bu örnek bir veri çerçevesini göz önüne alındığında

:

periods = 8 
dates = pd.date_range('20170101', periods=periods) 
rand_df = pd.DataFrame(np.random.randn(periods,4), index=dates, 
     columns=list('ABCD')) 

sorgu sözdizimi bir select deyimi bir "WHERE" kalma maddesi, birden çok filtre kullanmanızı sağlayacak aşağıdaki gibi.

rand_df.query("A < 0 or B < 0") 

Ek ayrıntılar için Pandas documentation'a bakın.

İlgili konular