Cách xác định xem Cột Pandas có chứa một giá trị cụ thể không


156

Tôi đang cố gắng xác định xem có một mục trong cột Pandas có giá trị cụ thể không. Tôi đã cố gắng để làm điều này với if x in df['id']. Tôi nghĩ rằng điều này đang hoạt động, ngoại trừ khi tôi cho nó một giá trị mà tôi biết không có trong cột 43 in df['id']thì nó vẫn trả về True. Khi tôi tập hợp vào một khung dữ liệu chỉ chứa các mục khớp với id bị thiếu df[df['id'] == 43], rõ ràng, không có mục nào trong đó. Làm cách nào để xác định xem một cột trong khung dữ liệu Pandas có chứa một giá trị cụ thể không và tại sao phương thức hiện tại của tôi không hoạt động? (FYI, tôi có cùng một vấn đề khi tôi sử dụng cách thực hiện trong câu trả lời này cho một câu hỏi tương tự).

Câu trả lời:


183

in của Sê-ri kiểm tra xem giá trị có trong chỉ mục hay không:

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

Một tùy chọn là để xem nếu nó trong các giá trị duy nhất :

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

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

hoặc một bộ trăn:

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

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

Như @DSM đã chỉ ra, có thể hiệu quả hơn (đặc biệt nếu bạn chỉ làm điều này cho một giá trị) để chỉ sử dụng trực tiếp trên các giá trị:

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

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

2
Tôi không muốn biết liệu nó có nhất thiết phải không, chủ yếu tôi muốn biết nếu nó ở đó.
Michael

24
Tôi nghĩ 'a' in s.valuesnên nhanh hơn cho Series dài.
DSM

4
@AndyHayden Bạn có biết tại sao, vì 'a' in s, gấu trúc chọn kiểm tra chỉ số thay vì các giá trị của chuỗi không? Trong từ điển họ kiểm tra các khóa, nhưng một chuỗi gấu trúc sẽ hoạt động giống như một danh sách hoặc mảng hơn, phải không?
Lôi

3
Bắt đầu từ gấu trúc 0.24.0, sử dụng s.valuesdf.valuesrất mất phương hướng. Xem này . Ngoài ra, s.valuesthực sự là chậm hơn nhiều trong một số trường hợp.
Qusai Alothman

1
@QusaiAlothman không .to_numpyhoặc .arraycó sẵn trên Sê-ri, vì vậy tôi không hoàn toàn chắc chắn họ đang ủng hộ phương án nào (Tôi không đọc "rất nản lòng"). Trên thực tế, họ đang nói rằng. Giá trị có thể không trả về một mảng numpy, ví dụ như trong trường hợp phân loại ... nhưng điều đó vẫn tốt innhư mong đợi (thực sự hiệu quả hơn là đối tác mảng numpy)
Andy Hayden

27

Bạn cũng có thể sử dụng pandas.Series.isin mặc dù nó dài hơn một chút so với '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

Nhưng cách tiếp cận này có thể linh hoạt hơn nếu bạn cần khớp nhiều giá trị cùng một lúc cho DataFrame (xem 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

Bạn cũng có thể sử dụng hàm DataFrame.any () :s.isin(['a']).any()
thando

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

di found.count()chúc chứa số lượng trận đấu

Và nếu nó là 0 thì có nghĩa là chuỗi không được tìm thấy trong Cột.


2
làm việc cho tôi, nhưng tôi đã sử dụng len (được tìm thấy) để có được số đếm
kztd

1
Có len (tìm thấy) là một lựa chọn tốt hơn.
Shahir Ansari

1
Cách tiếp cận này hiệu quả với tôi nhưng tôi phải bao gồm các tham số na=Falseregex=Falsecho trường hợp sử dụng của mình, như đã giải thích ở đây: pandas.pydata.org/pandas-docs/ sóng / reference / api / Mỉn
Mabyn

1
Nhưng string.contains thực hiện tìm kiếm chuỗi con. Ví dụ: Nếu có một giá trị gọi là "head_hunter". Vượt qua "đầu" trong str.contains khớp và cho True là sai.
karthikeyan

@karthikeyan Nó không sai. Phụ thuộc vào bối cảnh tìm kiếm của bạn. Điều gì nếu bạn đang tìm kiếm địa chỉ hoặc sản phẩm. Bạn sẽ cần tất cả các sản phẩm phù hợp với mô tả.
Shahir Ansari

6

Tôi đã làm một vài bài kiểm tra đơn giản:

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)

Điều thú vị là không có vấn đề gì nếu bạn tra cứu 9 hoặc 999999, có vẻ như mất khoảng thời gian tương tự bằng cách sử dụng cú pháp trong (phải sử dụng tìm kiếm nhị phân)

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)

Có vẻ như sử dụng x.values ​​là nhanh nhất, nhưng có lẽ có một cách thanh lịch hơn trong gấu trúc?


Sẽ thật tuyệt nếu bạn thay đổi thứ tự kết quả từ nhỏ nhất sang lớn nhất. Công việc tốt đẹp!
smm

4

Hoặc sử dụng Series.tolisthoặc 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.tolistlập một danh sách về a Series, và một cái khác tôi chỉ nhận được một boolean Seriestừ thông thường Series, sau đó kiểm tra xem có bất kỳ Trues nào trong boolean không Series.


1

Điều kiện đơn giản:

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

1

Sử dụng

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

Nếu xcó mặt idthì nó sẽ trả về danh sách các chỉ mục nơi nó hiện diện, nếu không nó sẽ đưa ra một danh sách trống.



0

Giả sử bạn dataframe trông như:

nhập mô tả hình ảnh ở đây

Bây giờ bạn muốn kiểm tra xem tên tệp "80900026941984" có xuất hiện trong khung dữ liệu hay không.

Bạn chỉ có thể viết:

if sum(df["filename"].astype("str").str.contains("80900026941984")) > 0:
    print("found")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.