Mengabaikan NaN dengan str.contains

117

Saya ingin menemukan baris yang berisi string, seperti:

DF[DF.col.str.contains("foo")]

Namun, ini gagal karena beberapa elemen adalah NaN:

ValueError: tidak dapat mengindeks dengan vektor yang mengandung nilai NA / NaN

Jadi saya menggunakan yang dikaburkan

DF[DF.col.notnull()][DF.col.dropna().str.contains("foo")]

Apakah ada cara yang lebih baik?

Emre
sumber

Jawaban:

226

Ada bendera untuk itu:

In [11]: df = pd.DataFrame([["foo1"], ["foo2"], ["bar"], [np.nan]], columns=['a'])

In [12]: df.a.str.contains("foo")
Out[12]:
0     True
1     True
2    False
3      NaN
Name: a, dtype: object

In [13]: df.a.str.contains("foo", na=False)
Out[13]:
0     True
1     True
2    False
3    False
Name: a, dtype: bool

Lihat str.replacedokumennya:

na: NaN default, isi nilai untuk nilai yang hilang.


Jadi, Anda dapat melakukan hal berikut:

In [21]: df.loc[df.a.str.contains("foo", na=False)]
Out[21]:
      a
0  foo1
1  foo2
Andy Hayden
sumber
2
Di sini saya memiliki situasi di mana adiisi dari CSV, dan akolom berisi string "nan". pandas"secara cerdas" mengubahnya menjadi NaNdan mulai mengeluh ketika saya mencoba melakukannya df.a.str.contains(). Jadi ya protip: pastikan untuk mengatur jenis kolom read_csv()atau setelah itu lakukan sesuatu seperti df = df.where(pandas.notnull(df), "nan")LOL
dmn
Mengapa df.locdan tidak adil df?
PascalVKooten
@PascalVKooten juga baik-baik saja, ilike .loc karena imo itu sedikit lebih eksplisit.
Andy Hayden
1
Ya menyelamatkan saya ... jika ini tidak ada di sini, saya pikir saya akan melalui mimpi buruk dua minggu membenturkan kepala saya ke dinding :-) pasti bernilai +1, lol
Maju U10
5
Lol mengapa tidak default ini?
ifly6
8

Selain jawaban di atas, saya akan mengatakan untuk kolom yang tidak memiliki nama kata tunggal, Anda dapat menggunakan: -

df[df['Product ID'].str.contains("foo") == True]

Semoga ini membantu.

Harry_pb
sumber
0

Saya tidak 100% tentang mengapa (sebenarnya datang ke sini untuk mencari jawabannya), tetapi ini juga berfungsi, dan tidak perlu mengganti semua nilai nan.

import pandas as pd
import numpy as np

df = pd.DataFrame([["foo1"], ["foo2"], ["bar"], [np.nan]], columns=['a'])

newdf = df.loc[df['a'].str.contains('foo') == True]

Bekerja dengan atau tanpa .loc.

Saya tidak tahu mengapa ini berfungsi, karena saya memahaminya ketika Anda mengindeks dengan tanda kurung, panda mengevaluasi apa pun yang ada di dalam braket sebagai Trueatau False. Saya tidak tahu mengapa membuat frasa di dalam tanda kurung 'ekstra boolean' memiliki efek apa pun.

Nate Taylor
sumber
0

Anda juga bisa pola:

DF[DF.col.str.contains(pat = '(foo)', regex = True) ]
Aliakbar Hosseinzadeh
sumber
-3
import folium
import pandas

data= pandas.read_csv("maps.txt")

lat = list(data["latitude"])
lon = list(data["longitude"])

map= folium.Map(location=[31.5204, 74.3587], zoom_start=6, tiles="Mapbox Bright")

fg = folium.FeatureGroup(name="My Map")

for lt, ln in zip(lat, lon):
c1 = fg.add_child(folium.Marker(location=[lt, ln], popup="Hi i am a Country",icon=folium.Icon(color='green')))

child = fg.add_child(folium.Marker(location=[31.5204, 74.5387], popup="Welcome to Lahore", icon= folium.Icon(color='green')))

map.add_child(fg)

map.save("Lahore.html")


Traceback (most recent call last):
  File "C:\Users\Ryan\AppData\Local\Programs\Python\Python36-32\check2.py", line 14, in <module>
    c1 = fg.add_child(folium.Marker(location=[lt, ln], popup="Hi i am a Country",icon=folium.Icon(color='green')))
  File "C:\Users\Ryan\AppData\Local\Programs\Python\Python36-32\lib\site-packages\folium\map.py", line 647, in __init__
    self.location = _validate_coordinates(location)
  File "C:\Users\Ryan\AppData\Local\Programs\Python\Python36-32\lib\site-packages\folium\utilities.py", line 48, in _validate_coordinates
    'got:\n{!r}'.format(coordinates))
ValueError: Location values cannot contain NaNs, got:
[nan, nan]
Faheem Alvi
sumber
Ini bukanlah jawaban.
ifly6