팬더 열에 특정 값이 포함되어 있는지 확인하는 방법


156

Pandas 열에 특정 값을 가진 항목이 있는지 확인하려고합니다. 나는 이것을 시도했다 if x in df['id']. 나는 그것이 내가 43 in df['id']반환 한 열에 없다는 것을 알고있는 값을 먹일 때를 제외하고는 이것이 효과가 있다고 생각 했습니다 True. 누락 된 ID와 일치하는 항목 만 포함하는 데이터 프레임의 하위 집합을 df[df['id'] == 43]만들면 분명히 항목이 없습니다. Pandas 데이터 프레임의 열에 특정 값이 포함되어 있는지 확인하고 현재 방법이 작동하지 않는 이유는 무엇입니까? (참고로, 비슷한 질문에 대한 이 답변 의 구현을 사용할 때 동일한 문제가 있습니다 ).

답변:


183

in 시리즈의 값이 값이 색인에 있는지 확인합니다.

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

한 가지 옵션은 고유 한 값 인지 확인하는 것입니다 .

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

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

또는 파이썬 세트 :

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

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

@DSM이 지적했듯이 값에 직접 사용하는 것이 더 효율적일 수 있습니다 (특히 하나의 값 으로이 작업을 수행하는 경우).

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

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

2
나는 그것이 고유한지 여부를 알고 싶지 않습니다. 주로 그것이 있는지 알고 싶습니다.
Michael

24
'a' in s.values긴 시리즈의 경우 더 빠를 것이라고 생각 합니다.
DSM

4
@AndyHayden 'a' in s팬더가 시리즈의 값이 아닌 인덱스를 확인하는 이유를 알고 있습니까? 사전에서 키를 확인하지만 팬더 시리즈는 목록이나 배열처럼 작동해야합니다.
레이

3
, 팬더 0.24.0부터 시작 사용 s.valuesdf.values높은 discoraged된다. 참조 . 또한 s.values어떤 경우에는 실제로 훨씬 느립니다.
Qusai Alothman 19

1
@QusaiAlothman 은 .to_numpy또는 .array시리즈에서 사용할 수 없으므로 그들이 어떤 대안을 옹호하는지 확실하지 않습니다 ( "저희는 낙관적 "이라고 읽지 않습니다). 사실 그들은 .values이 범주의 경우 예를 들면 NumPy와 배열을 반환하지 않을 수 있음을 말 ...하지만하고 그의 미세과 같은 in것이다 여전히 작업 (이 NumPy와 배열의 대응이 있다는 사실보다 효율적으로) 예상대로
앤디 헤이든

27

당신은 또한 사용할 수 있습니다 pandas.Series.isin를 가 조금보다 더 오래 비록 '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

그러나 DataFrame에 대해 여러 값을 한 번에 일치시켜야하는 경우이 방법이 더 유연 할 수 있습니다 ( 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

DataFrame.any () 함수를 사용할 수도 있습니다 .s.isin(['a']).any()
thando

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

found.count()의지는 경기의 수를 포함

그리고 0이면 열에서 문자열을 찾을 수 없음을 의미합니다.


2
나를 위해 일했지만, 나는 len (found)를 사용하여 수를 얻었습니다
kztd

1
예 len (found)이 다소 더 나은 옵션입니다.
Shahir Ansari

1
이 접근법은 저에게 효과적이지만 여기에 설명 된대로 매개 변수 na=Falseregex=False사용 사례 를 포함해야했습니다 . pandas.pydata.org/pandas-docs/stable/reference/api/…
Mabyn

1
그러나 string.contains는 하위 문자열 검색을 수행합니다. 예 : "head_hunter"라는 값이있는 경우 str.에 "head"를 전달하면 일치하는 항목이 포함되고 True가 잘못됩니다.
karthikeyan

@karthikeyan 잘못이 아닙니다. 검색 환경에 따라 다릅니다. 주소 나 제품을 검색하는 경우 어떻게됩니까? 설명에 맞는 모든 제품이 필요합니다.
샤 히르 안사리

6

몇 가지 간단한 테스트를 수행했습니다.

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)

흥미롭게도 9 또는 999999를 조회하더라도 중요하지 않습니다 .in 구문을 사용하는 데 거의 같은 시간이 걸리는 것처럼 보입니다 (이진 검색을 사용해야 함)

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를 사용하는 것이 가장 빠르지 만 팬더에는 더 우아한 방법이 있습니까?


결과 순서를 최소에서 최대로 변경하면 좋을 것입니다. 잘 하셨어요!
smm

4

또는 사용 Series.tolist하거나 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.tolist에 대한 목록을 만들고 Series다른 하나 Series는 일반에서 부울을 얻은 Series다음 True부울에 s 가 있는지 확인합니다 Series.


1

간단한 조건 :

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

1

사용하다

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

경우 x에 존재하는 id다음이 존재하는 곳은 빈 목록을 제공, 다른 인덱스의 목록을 반환합니다.



0

데이터 프레임이 다음과 같다고 가정하십시오.

여기에 이미지 설명을 입력하십시오

이제 파일 이름 "80900026941984"가 데이터 프레임에 있는지 확인하고 싶습니다.

간단히 쓸 수 있습니다 :

if sum(df["filename"].astype("str").str.contains("80900026941984")) > 0:
    print("found")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.