Pandalar Bir Dizi nasıl filtrelenir?


94

Groupby ('ad') yaptıktan sonra buna benzer bir Serim var ve diğer sütunda ortalama () işlevini kullandım

name
383      3.000000
663      1.000000
726      1.000000
737      9.000000
833      8.166667

Biri bana 1.000000 ortalama değerlere sahip satırları nasıl filtreleyeceğimi gösterebilir mi? Teşekkürler ve yardımın için çok minnettarım.


Peki, belirli bir koşula göre bir seriyi nasıl filtrelersiniz?

Yanıtlar:


127
In [5]:

import pandas as pd

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

s = pd.Series(test)
s = s[s != 1]
s
Out[0]:
383    3.000000
737    9.000000
833    8.166667
dtype: float64

10
Aşağıdaki cevapları zincirlenebildikleri için tercih ediyorum (yani tanımlamaya sve sonra ifadede iki kez kullanmaya gerek yok ). Sadece 0.18 pandalardan çalışır.
IanS

Ayrıca piRSquared en zamanlama karşılaştırmaları bkz cevap .
IanS

63

Pandalar 0.18+ sürümünden itibaren aşağıdaki gibi bir dizi filtreleme yapılabilir

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

pd.Series(test).where(lambda x : x!=1).dropna()

Ödeme: http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improements


3
Yöntem zincirleme ile çok daha hoş (ve bana Spark'ı hatırlatıyor)
Dylan Hogg

Doğru ama Spark bu durumda daha sezgisel bir şey yapıyor: sadece yüklemle eşleşmeyen satırlardan kurtuluyor, bu, ben dokümanı okuyana kadar bana açıkça gereksiz görünen ".dropna ()" kısmını kullanmamak anlamına geliyor. Isırıldı: D
Florent Moiny

44

As DACW işaret vardır yöntem zincirleme gelişmeler çok güzel aradığınızı yapmak pandalar 0.18.1 yılında.

Kullanmak yerine .where, işlevinizi .locdizin oluşturucuya veya Seri dizin oluşturucuya aktarabilir []ve şu çağrıları engelleyebilirsiniz .dropna:

test = pd.Series({
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
})

test.loc[lambda x : x!=1]

test[lambda x: x!=1]

Benzer davranış, DataFrame ve NDFrame sınıflarında desteklenir.


2
Bu benim en sevdiğim cevap ve aynı zamanda uyuşukluğa inmeden en hızlısı gibi görünüyor (zamanlama karşılaştırmalarına bakın)
IanS

21

Bunu yapmanın hızlı bir yolu numpy, temeldeki dizileri dilimlemek için kullanarak yeniden yapılandırmaktır . Aşağıdaki zamanlamalara bakın.

mask = s.values != 1
pd.Series(s.values[mask], s.index[mask])

0
383    3.000000
737    9.000000
833    8.166667
dtype: float64

saf zamanlama

görüntü açıklamasını buraya girin


, Yöntemini beğendim, çoklu maskelerim varsa ne olduğunu bilmek istiyorum. Thx
Menglong Li

1
@MenglongLi bağlıdır, bir soru sormalısınız. Büyük olasılıkla, bunları & ile birleştirirsiniz. mask = mask1 & mask2
piRSquared

6

Başka bir yol, önce bir DataFrame'e dönüştürmek ve sorgu yöntemini kullanmaktır (numexpr'iniz kurulu olduğunu varsayarak):

import pandas as pd

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

s = pd.Series(test)
s.to_frame(name='x').query("x != 1")

Bir koşulu dizge olarak
geçirmenin

1
Bu, bir veri çerçevesinin tüm ek yükünü ekler ve çok yavaş olacaktır.
fantabolous

5

Zincirleme bir işlemi seviyorsanız, compressişlevi de kullanabilirsiniz :

test = pd.Series({
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
})

test.compress(lambda x: x != 1)

# 383    3.000000
# 737    9.000000
# 833    8.166667
# dtype: float64

1

Benim durumumda , değerlerin karakter demetleri olduğu bir panda Serim vardı :

Out[67]
0    (H, H, H, H)
1    (H, H, H, T)
2    (H, H, T, H)
3    (H, H, T, T)
4    (H, T, H, H)

Bu nedenle, diziyi filtrelemek için indekslemeyi kullanabilirdim, ancak ihtiyacım olan indeksi oluşturmak için apply. Koşulum "tam olarak bir 'H' içeren tüm demetleri bul".

series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]

Bunun "zincirlenebilir" olmadığını kabul ediyorum (yani series_of_tuplesiki kez tekrarladığıma dikkat edin ; herhangi bir geçici seriyi bir değişkene kaydetmeniz gerekir, böylece üzerinde apply (...) çağırabilirsiniz).

Ayrıca söz konusu olabilir diğer yöntemler (yanında .apply(...)olabilir) bir Boole endeksi üretmek için elementwise çalışırlar.

Zincirleme işlevleri kullanan diğer birçok yanıt (kabul edilen yanıt dahil):

  • .compress()
  • .where()
  • .loc[]
  • []

Bunlar , bu serideki bireysel değerlere değil Seriye uygulanan çağrılabilirleri (lambdalar) kabul eder !

Bu nedenle dizilerim, yukarıdaki koşulumu / çağrılabilir / lambda'mı, zincirlenebilir işlevlerden herhangi biriyle kullanmaya çalıştığımda garip davranıyordu, örneğin .loc[]:

series_of_tuples.loc[lambda x: x.count('H')==1]

Şu hatayı üretir:

KeyError: 'H Düzeyi adla aynı olmalıdır (Yok)'

Kafam çok karışmıştı, ancak Series.count series_of_tuples.count(...)işlevini kullanıyor gibi görünüyor , ki bu istediğim şey değildi.

Alternatif bir veri yapısının daha iyi olabileceğini kabul ediyorum:

  • Kategori veri türü?
  • Bir Veri Çerçevesi (başlığın her bir öğesi bir sütun haline gelir)
  • Bir dizi dizge (sadece tupleları bir araya getirin):

Bu, bir dizi dize oluşturur (örn. Tuple'ı birleştirerek; demetteki karakterleri tek bir dizede birleştirerek)

series_of_tuples.apply(''.join)

Böylece zincirlenebilir olanı kullanabilirimSeries.str.count

series_of_tuples.apply(''.join).str.count('H')==1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.