Bir Panda Sütununun belirli bir değer içerip içermediğini belirleme


156

Belirli bir değere sahip bir pandalar sütununda bir giriş olup olmadığını belirlemek için çalışıyorum. Bunu yapmaya çalıştım if x in df['id']. Bunun işe yaradığını düşündüm, ancak sütunda olmadığını bildiğim bir değer verdiğimde 43 in df['id']hala döndü True. Yalnızca eksik tanıtıcıyla eşleşen girdileri içeren bir veri çerçevesine alt kümeye girdiğimde df[df['id'] == 43], içinde hiç girdi yok. Panda veri çerçevesindeki bir sütunun belirli bir değer içerip içermediğini nasıl belirlerim ve geçerli yöntemim neden çalışmıyor? (Bilginize, benzer bir soruya bu cevapta uygulamayı kullandığımda aynı sorun yaşıyorum ).

Yanıtlar:


183

in bir Seri değerin dizinde olup olmadığını kontrol eder:

In [11]: s = pd.Series(list('abc'))

In [12]: s
Out[12]: 
0    a
1    b
2    c
dtype: object

In [13]: 1 in s
Out[13]: True

In [14]: 'a' in s
Out[14]: False

Bir seçenek, benzersiz değerlerde olup olmadığını görmektir :

In [21]: s.unique()
Out[21]: array(['a', 'b', 'c'], dtype=object)

In [22]: 'a' in s.unique()
Out[22]: True

veya bir python seti:

In [23]: set(s)
Out[23]: {'a', 'b', 'c'}

In [24]: 'a' in set(s)
Out[24]: True

@DSM tarafından işaret edildiği gibi, sadece doğrudan değerlerde kullanmak daha verimli olabilir (özellikle bunu sadece bir değer için yapıyorsanız):

In [31]: s.values
Out[31]: array(['a', 'b', 'c'], dtype=object)

In [32]: 'a' in s.values
Out[32]: True

2
Mutlaka benzersiz olup olmadığını bilmek istemiyorum, esas olarak orada olup olmadığını bilmek istiyorum.
Michael

24
'a' in s.valuesUzun Seriler için daha hızlı olması gerektiğini düşünüyorum .
DSM

4
@AndyHayden 'a' in sPandaların serinin değerlerinden ziyade dizini kontrol etmeyi neden seçtiğini biliyor musunuz ? Sözlüklerde anahtarları kontrol ederler, ancak bir panda serisi bir liste veya dizi gibi davranmalıdır, değil mi?
Lei

3
Pandalar 0.24.0'dan başlayarak, s.valuesve df.valueskullanımı son derece bozulmuştur. Bkz bu . Ayrıca, s.valuesbazı durumlarda aslında çok daha yavaştır.
Qusai Alothman

1
@QusaiAlothman ne .to_numpyya .arrayben tamamen emin onlar (ı "önerilmez" okumaz) savunan şeyin alternatifi değilim bu yüzden, bir Series mevcuttur. Aslında .values, örneğin kategorik bir durumda, nümerik bir dizi döndürmeyebilir diyorlar ... ama inyine de beklendiği gibi çalışacaktır (gerçekten daha verimli bir şekilde bu dizi dizi muadili olduğunu)
Andy Hayden

27

Ayrıca pandas.Series.isin'i biraz daha uzun olmasına rağmen kullanabilirsiniz 'a' in s.values:

In [2]: s = pd.Series(list('abc'))

In [3]: s
Out[3]: 
0    a
1    b
2    c
dtype: object

In [3]: s.isin(['a'])
Out[3]: 
0    True
1    False
2    False
dtype: bool

In [4]: s[s.isin(['a'])].empty
Out[4]: False

In [5]: s[s.isin(['z'])].empty
Out[5]: True

Ancak bir DataFrame için aynı anda birden fazla değeri eşleştirmeniz gerekiyorsa bu yaklaşım daha esnek olabilir (bkz. DataFrame.isin )

>>> df = DataFrame({'A': [1, 2, 3], 'B': [1, 4, 7]})
>>> df.isin({'A': [1, 3], 'B': [4, 7, 12]})
       A      B
0   True  False  # Note that B didn't match 1 here.
1  False   True
2   True   True

Ayrıca DataFrame.any () işlevini de kullanabilirsiniz :s.isin(['a']).any()
thando

17
found = df[df['Column'].str.contains('Text_to_search')]
print(found.count())

found.count()irade eşleşme sayısını içerir

Ve eğer 0 ise Sütunda dize bulunamadı demektir.


2
benim için çalıştı, ama saymak için len (bulundu) kullanılır
kztd

1
Evet len ​​(bulundu) biraz daha iyi bir seçenek.
Shahir Ansari

1
Bu yaklaşım benim için çalıştı ama burada açıklandığı gibi parametreleri na=Falseve regex=Falsekullanım durumumu dahil etmek zorunda kaldım : pandas.pydata.org/pandas-docs/stable/reference/api/…
Mabyn

1
Ancak string.contains bir alt dize araması yapar. Örn: "head_hunter" adlı bir değer varsa. Str.con içinde "head" geçmek maçlar içerir ve yanlış olan True verir.
karthikeyan

@karthikeyan Yanlış değil. Aramanızın içeriğine bağlıdır. Adresleri veya ürünleri arıyorsanız. Açıklamaya uyan tüm ürünlere ihtiyacınız olacak.
Shahir Ansari

6

Birkaç basit test yaptım:

In [10]: x = pd.Series(range(1000000))

In [13]: timeit 999999 in x.values
567 µs ± 25.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [15]: timeit x.isin([999999]).any()
9.54 ms ± 291 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [16]: timeit (x == 999999).any()
6.86 ms ± 107 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [17]: timeit 999999 in set(x)
79.8 ms ± 1.98 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [21]: timeit x.eq(999999).any()
7.03 ms ± 33.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [22]: timeit x.eq(9).any()
7.04 ms ± 60 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [24]: timeit 9 in x.values
666 µs ± 15.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

İlginçtir ki, 9 veya 999999'a bakmanız önemli değildir, sözdizimini kullanmak yaklaşık aynı zaman alır gibi görünüyor (ikili arama kullanıyor olmalıdır)

In [24]: timeit 9 in x.values
666 µs ± 15.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [25]: timeit 9999 in x.values
647 µs ± 5.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [26]: timeit 999999 in x.values
642 µs ± 2.11 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [27]: timeit 99199 in x.values
644 µs ± 5.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [28]: timeit 1 in x.values
667 µs ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

X.values ​​kullanmak en hızlı gibi görünüyor, ama belki pandalarda daha zarif bir yol var mı?


Sonuçların sırasını en küçükten en büyüğe değiştirirseniz harika olur. İyi iş!
smm

4

Veya Series.tolistveya kullanın Series.any:

>>> s = pd.Series(list('abc'))
>>> s
0    a
1    b
2    c
dtype: object
>>> 'a' in s.tolist()
True
>>> (s=='a').any()
True

Series.tolisthakkında bir liste yapar Seriesve diğeri ben sadece Seriesdüzenli bir boolean alıyorum Series, sonra Trueboolean herhangi bir s olup olmadığını kontrol Series.


1

Basit durum:

if any(str(elem) in ['a','b'] for elem in df['column'].tolist()):

1

kullanım

df[df['id']==x].index.tolist()

Eğer mevcutsa x, mevcut idolduğu indekslerin listesini döndürür, aksi takdirde boş bir liste verir.



0

Diyelim ki veri çerçevesi şöyle görünüyor:

resim açıklamasını buraya girin

Şimdi veri çerçevesinde "80900026941984" dosya adının bulunup bulunmadığını kontrol etmek istersiniz.

Basitçe şunu yazabilirsiniz:

if sum(df["filename"].astype("str").str.contains("80900026941984")) > 0:
    print("found")
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.