Làm cách nào để chọn các hàng từ DataFrame dựa trên các giá trị cột?


1959

Làm cách nào để chọn các hàng từ DataFramedựa trên các giá trị trong một số cột trong Python Pandas?

Trong SQL, tôi sẽ sử dụng:

SELECT *
FROM table
WHERE colume_name = some_value

Tôi đã cố gắng xem tài liệu về gấu trúc nhưng không tìm thấy câu trả lời ngay lập tức.



6
Đây là So sánh với SQL: pandas.pydata.org/pandas-docs/urdy/comparison_with_sql.html nơi bạn có thể chạy gấu trúc dưới dạng SQL.
i_thamary

Câu trả lời:


3768

Để chọn các hàng có giá trị cột bằng vô hướng, some_valuehãy sử dụng ==:

df.loc[df['column_name'] == some_value]

Để chọn các hàng có giá trị cột nằm trong một lần lặp, some_valueshãy sử dụng isin:

df.loc[df['column_name'].isin(some_values)]

Kết hợp nhiều điều kiện với &:

df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]

Lưu ý dấu ngoặc đơn. Do các quy tắc ưu tiên toán tử của Python , &liên kết chặt chẽ hơn <=>=. Vì vậy, các dấu ngoặc trong ví dụ cuối là cần thiết. Không có dấu ngoặc đơn

df['column_name'] >= A & df['column_name'] <= B

được phân tích thành

df['column_name'] >= (A & df['column_name']) <= B

dẫn đến giá trị Chân lý của Sê-ri là lỗi không rõ ràng .


Để chọn các hàng có giá trị cột không bằng nhau some_value , hãy sử dụng !=:

df.loc[df['column_name'] != some_value]

isintrả về Sê-ri boolean, vì vậy để chọn các hàng có giá trị không nằm trong some_values, hãy phủ định Sê-ri boolean bằng cách sử dụng ~:

df.loc[~df['column_name'].isin(some_values)]

Ví dụ,

import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split(),
                   'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
#      A      B  C   D
# 0  foo    one  0   0
# 1  bar    one  1   2
# 2  foo    two  2   4
# 3  bar  three  3   6
# 4  foo    two  4   8
# 5  bar    two  5  10
# 6  foo    one  6  12
# 7  foo  three  7  14

print(df.loc[df['A'] == 'foo'])

sản lượng

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Nếu bạn có nhiều giá trị bạn muốn đưa vào, hãy đặt chúng vào một danh sách (hoặc nói chung hơn, bất kỳ lần lặp nào) và sử dụng isin:

print(df.loc[df['B'].isin(['one','three'])])

sản lượng

     A      B  C   D
0  foo    one  0   0
1  bar    one  1   2
3  bar  three  3   6
6  foo    one  6  12
7  foo  three  7  14

Tuy nhiên, lưu ý rằng nếu bạn muốn làm điều này nhiều lần, sẽ hiệu quả hơn khi tạo chỉ mục trước, sau đó sử dụng df.loc:

df = df.set_index(['B'])
print(df.loc['one'])

sản lượng

       A  C   D
B              
one  foo  0   0
one  bar  1   2
one  foo  6  12

hoặc, để bao gồm nhiều giá trị từ chỉ mục sử dụng df.index.isin:

df.loc[df.index.isin(['one','two'])]

sản lượng

       A  C   D
B              
one  foo  0   0
one  bar  1   2
two  foo  2   4
two  foo  4   8
two  bar  5  10
one  foo  6  12

19
Trên thực tế, df [df ['colume_name'] == some_value] cũng hoạt động. Nhưng nỗ lực đầu tiên của tôi, df.where (df ['colume_name'] == some_value) không hoạt động ... không chắc tại sao ...
szli

13
Khi bạn sử dụng df.where(condition), điều kiện phải có hình dạng giống như df.
unutbu


8
FYI: Nếu bạn muốn chọn một hàng dựa trên hai nhãn (hoặc nhiều hơn) (yêu cầu cả hai hoặc một trong hai), hãy xem stackoverflow.com/questions/31756340/ Lỗi
Shane

7
Kể từ khi df[df['column_name'] == some_value]làm việc, tại sao chúng ta cần thêm .locở đây?
qqqwww

313

Có một số cách để chọn hàng từ khung dữ liệu gấu trúc:

  1. Lập chỉ mục Boolean ( df[df['col'] == value])
  2. Lập chỉ mục vị trí ( df.iloc[...])
  3. Lập chỉ mục nhãn ( df.xs(...))
  4. df.query(...) API

Dưới đây tôi chỉ cho bạn ví dụ về từng ví dụ, với lời khuyên khi sử dụng các kỹ thuật nhất định. Giả sử tiêu chí của chúng tôi là cột 'A'=='foo'

(Lưu ý về hiệu suất: Đối với mỗi loại cơ sở, chúng tôi có thể giữ mọi thứ đơn giản bằng cách sử dụng API gấu trúc hoặc chúng tôi có thể mạo hiểm bên ngoài API, thường vào numpyvà tăng tốc mọi thứ.)


Thiết lập
Điều đầu tiên chúng ta cần là xác định một điều kiện sẽ đóng vai trò là tiêu chí của chúng tôi để chọn hàng. Chúng ta sẽ bắt đầu với trường hợp của OP column_name == some_valuevà bao gồm một số trường hợp sử dụng phổ biến khác.

Vay từ @unutbu:

import pandas as pd, numpy as np

df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split(),
                   'C': np.arange(8), 'D': np.arange(8) * 2})

1. Lập chỉ mục Boolean

... Lập chỉ mục Boolean yêu cầu tìm giá trị thực của 'A'cột của mỗi hàng bằng 'foo', sau đó sử dụng các giá trị thật đó để xác định hàng nào sẽ giữ. Thông thường, chúng tôi sẽ đặt tên cho loạt bài này, một loạt các giá trị thật , mask. Chúng tôi sẽ làm như vậy ở đây là tốt.

mask = df['A'] == 'foo'

Sau đó chúng ta có thể sử dụng mặt nạ này để cắt hoặc lập chỉ mục khung dữ liệu

df[mask]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Đây là một trong những cách đơn giản nhất để thực hiện nhiệm vụ này và nếu hiệu suất hoặc trực giác không phải là vấn đề, thì đây nên là phương pháp bạn chọn. Tuy nhiên, nếu hiệu suất là một mối quan tâm, thì bạn có thể muốn xem xét một cách khác để tạo mask.


2. Lập chỉ mục vị trí

Lập chỉ mục vị trí ( df.iloc[...]) có các trường hợp sử dụng, nhưng đây không phải là một trong số chúng. Để xác định vị trí cắt lát, trước tiên chúng ta cần thực hiện phân tích boolean tương tự mà chúng ta đã làm ở trên. Điều này khiến chúng tôi thực hiện thêm một bước để hoàn thành nhiệm vụ tương tự.

mask = df['A'] == 'foo'
pos = np.flatnonzero(mask)
df.iloc[pos]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

3. Lập chỉ mục nhãn

Lập chỉ mục nhãn có thể rất tiện dụng, nhưng trong trường hợp này, chúng tôi lại làm nhiều việc hơn mà không có lợi

df.set_index('A', append=True, drop=False).xs('foo', level=1)

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

4. df.query()API

pd.DataFrame.querylà một cách rất thanh lịch / trực quan để thực hiện nhiệm vụ này, nhưng thường chậm hơn. Tuy nhiên , nếu bạn chú ý đến thời gian bên dưới, đối với dữ liệu lớn, truy vấn rất hiệu quả. Hơn cả cách tiếp cận tiêu chuẩn và có độ lớn tương tự như gợi ý tốt nhất của tôi.

df.query('A == "foo"')

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Sở thích của tôi là sử dụng Boolean mask

Cải tiến thực tế có thể được thực hiện bằng cách sửa đổi cách chúng tôi tạo ra Boolean mask.

maskthay thế 1
Sử dụng numpymảng cơ bản và bỏ qua việc tạo ra một mảng khácpd.Series

mask = df['A'].values == 'foo'

Cuối cùng, tôi sẽ hiển thị các bài kiểm tra thời gian hoàn chỉnh hơn, nhưng hãy xem mức tăng hiệu suất mà chúng tôi có được bằng cách sử dụng khung dữ liệu mẫu. Đầu tiên, chúng tôi xem xét sự khác biệt trong việc tạo ramask

%timeit mask = df['A'].values == 'foo'
%timeit mask = df['A'] == 'foo'

5.84 µs ± 195 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
166 µs ± 4.45 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Đánh giá maskvới numpymảng nhanh hơn ~ 30 lần. Điều này một phần là do numpyđánh giá thường nhanh hơn. Điều này cũng một phần do thiếu chi phí cần thiết để xây dựng một chỉ mục và một pd.Seriesđối tượng tương ứng .

Tiếp theo, chúng ta sẽ xem xét thời gian để cắt với cái này maskso với cái kia.

mask = df['A'].values == 'foo'
%timeit df[mask]
mask = df['A'] == 'foo'
%timeit df[mask]

219 µs ± 12.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
239 µs ± 7.03 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Hiệu suất đạt được không như phát âm. Chúng tôi sẽ xem nếu điều này giữ qua thử nghiệm mạnh mẽ hơn.


maskthay thế 2
Chúng ta cũng có thể xây dựng lại khung dữ liệu. Có một sự cảnh báo lớn khi xây dựng lại một dataframe Bạn phải chăm sóc dtypeskhi làm như vậy!

Thay vì df[mask]chúng tôi sẽ làm điều này

pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)

Nếu khung dữ liệu là loại hỗn hợp, ví dụ của chúng tôi là, thì khi chúng tôi nhận được df.valuesmảng kết quả là dtype objectvà do đó, tất cả các cột của khung dữ liệu mới sẽ là dtype object. Do đó đòi hỏi astype(df.dtypes)và giết chết bất kỳ hiệu suất tiềm năng.

%timeit df[m]
%timeit pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)

216 µs ± 10.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.43 ms ± 39.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Tuy nhiên, nếu khung dữ liệu không phải là loại hỗn hợp, đây là một cách rất hữu ích để làm điều đó.

Được

np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10, 5)), columns=list('ABCDE'))

d1

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
2  0  2  0  4  9
3  7  3  2  4  3
4  3  6  7  7  4
5  5  3  7  5  9
6  8  7  6  4  7
7  6  2  6  6  5
8  2  8  7  5  8
9  4  7  6  1  5    

%%timeit
mask = d1['A'].values == 7
d1[mask]

179 µs ± 8.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Đấu với

%%timeit
mask = d1['A'].values == 7
pd.DataFrame(d1.values[mask], d1.index[mask], d1.columns)

87 µs ± 5.12 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Chúng tôi cắt thời gian một nửa.


maskthay thế 3
@unutbu cũng chỉ cho chúng tôi cách sử dụng pd.Series.isinđể tính toán cho từng yếu tố df['A']tồn tại trong một tập hợp các giá trị. Điều này ước tính cho cùng một điều nếu tập hợp các giá trị của chúng tôi là một tập hợp của một giá trị, cụ thể là 'foo'. Nhưng nó cũng khái quát để bao gồm các bộ giá trị lớn hơn nếu cần. Hóa ra, điều này vẫn còn khá nhanh mặc dù nó là một giải pháp tổng quát hơn. Sự mất mát thực sự duy nhất là ở trực giác cho những người không quen thuộc với khái niệm này.

mask = df['A'].isin(['foo'])
df[mask]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Tuy nhiên, như trước đây, chúng ta có thể sử dụng numpyđể cải thiện hiệu suất trong khi hy sinh hầu như không có gì. Chúng tôi sẽ sử dụngnp.in1d

mask = np.in1d(df['A'].values, ['foo'])
df[mask]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Thời gian
tôi sẽ bao gồm các khái niệm khác được đề cập trong các bài viết khác để tham khảo.
Mã dưới đây

Mỗi Cột trong bảng này biểu thị một khung dữ liệu có độ dài khác nhau mà chúng tôi kiểm tra từng chức năng. Mỗi cột hiển thị thời gian tương đối được thực hiện, với chức năng nhanh nhất được cung cấp một chỉ số cơ bản là 1.0.

res.div(res.min())

                         10        30        100       300       1000      3000      10000     30000
mask_standard         2.156872  1.850663  2.034149  2.166312  2.164541  3.090372  2.981326  3.131151
mask_standard_loc     1.879035  1.782366  1.988823  2.338112  2.361391  3.036131  2.998112  2.990103
mask_with_values      1.010166  1.000000  1.005113  1.026363  1.028698  1.293741  1.007824  1.016919
mask_with_values_loc  1.196843  1.300228  1.000000  1.000000  1.038989  1.219233  1.037020  1.000000
query                 4.997304  4.765554  5.934096  4.500559  2.997924  2.397013  1.680447  1.398190
xs_label              4.124597  4.272363  5.596152  4.295331  4.676591  5.710680  6.032809  8.950255
mask_with_isin        1.674055  1.679935  1.847972  1.724183  1.345111  1.405231  1.253554  1.264760
mask_with_in1d        1.000000  1.083807  1.220493  1.101929  1.000000  1.000000  1.000000  1.144175

Bạn sẽ nhận thấy rằng thời gian nhanh nhất dường như được chia sẻ giữa mask_with_valuesmask_with_in1d

res.T.plot(loglog=True)

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

Chức năng

def mask_standard(df):
    mask = df['A'] == 'foo'
    return df[mask]

def mask_standard_loc(df):
    mask = df['A'] == 'foo'
    return df.loc[mask]

def mask_with_values(df):
    mask = df['A'].values == 'foo'
    return df[mask]

def mask_with_values_loc(df):
    mask = df['A'].values == 'foo'
    return df.loc[mask]

def query(df):
    return df.query('A == "foo"')

def xs_label(df):
    return df.set_index('A', append=True, drop=False).xs('foo', level=-1)

def mask_with_isin(df):
    mask = df['A'].isin(['foo'])
    return df[mask]

def mask_with_in1d(df):
    mask = np.in1d(df['A'].values, ['foo'])
    return df[mask]

Kiểm tra

res = pd.DataFrame(
    index=[
        'mask_standard', 'mask_standard_loc', 'mask_with_values', 'mask_with_values_loc',
        'query', 'xs_label', 'mask_with_isin', 'mask_with_in1d'
    ],
    columns=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
    dtype=float
)

for j in res.columns:
    d = pd.concat([df] * j, ignore_index=True)
    for i in res.index:a
        stmt = '{}(d)'.format(i)
        setp = 'from __main__ import d, {}'.format(i)
        res.at[i, j] = timeit(stmt, setp, number=50)

Thời gian đặc biệt
Nhìn vào trường hợp đặc biệt khi chúng ta có một đối tượng duy nhất dtypecho toàn bộ khung dữ liệu. Mã dưới đây

spec.div(spec.min())

                     10        30        100       300       1000      3000      10000     30000
mask_with_values  1.009030  1.000000  1.194276  1.000000  1.236892  1.095343  1.000000  1.000000
mask_with_in1d    1.104638  1.094524  1.156930  1.072094  1.000000  1.000000  1.040043  1.027100
reconstruct       1.000000  1.142838  1.000000  1.355440  1.650270  2.222181  2.294913  3.406735

Hóa ra, việc tái thiết không đáng để vượt qua vài trăm hàng.

spec.T.plot(loglog=True)

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

Chức năng

np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10, 5)), columns=list('ABCDE'))

def mask_with_values(df):
    mask = df['A'].values == 'foo'
    return df[mask]

def mask_with_in1d(df):
    mask = np.in1d(df['A'].values, ['foo'])
    return df[mask]

def reconstruct(df):
    v = df.values
    mask = np.in1d(df['A'].values, ['foo'])
    return pd.DataFrame(v[mask], df.index[mask], df.columns)

spec = pd.DataFrame(
    index=['mask_with_values', 'mask_with_in1d', 'reconstruct'],
    columns=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
    dtype=float
)

Kiểm tra

for j in spec.columns:
    d = pd.concat([df] * j, ignore_index=True)
    for i in spec.index:
        stmt = '{}(d)'.format(i)
        setp = 'from __main__ import d, {}'.format(i)
        spec.at[i, j] = timeit(stmt, setp, number=50)

6
Câu trả lời tuyệt vời! 2 câu hỏi mặc dù, i) làm thế nào để .iloc(numpy.where(..))so sánh trong chương trình này? ii) bạn có muốn xếp hạng giống nhau khi sử dụng nhiều điều kiện không?
posdef

3
Để thực hiện pd.Series.isin, lưu ý nó không sử dụng np.in1ddưới mui xe trong một kịch bản cụ thể, sử dụng khash ở người khác, và mặc nhiên áp dụng một trade-off giữa chi phí băm so với hiệu suất trong các tình huống cụ thể. Câu trả lời này có nhiều chi tiết hơn.
jpp

1
Ở mức 9 màn hình, đây là cách quá tải cho người dùng mới hoặc thậm chí trung gian. Bạn có thể và nên tự tóm tắt tl; dr trong đoạn đầu tiên.
smci

@piRSquared Scaling vấn đề bạn sẽ quan tâm, @piRSquared, cũng để gửi kinh nghiệm của bạn về như thế nào thực tế [{P|EXP}TIME] - và [{C|P|EXP}SPACE]- chi phí của việc sử dụng các hình thức nêu trên đề xuất của khối cú pháp (xử lý từ trên xuống toàn bộ dataframes cùng một lúc) phát triển , cụ thể là khi thu nhỏ đến một số ~1E6, ~1E9, ~1E12hàng? Cảm ơn đã cho chúng tôi xem toàn bộ hình ảnh, thưa ông. Các bài đọc điểm chuẩn định lượng [min, Avg, MAX, StDev]luôn được chào đón, vì cả giá trị minMAXgiá trị đều đi kèm với sự Mean/StDevgiảm bớt của đợt.
user3666197

Câu trả lời tuyệt vời! Các truy vấn đã giải quyết vấn đề của tôi!
Pavlos Ponos

281

tl; dr

Những con gấu trúc tương đương với

select * from table where column_name = some_value

table[table.column_name == some_value]

Nhiều điều kiện:

table[(table.column_name == some_value) | (table.column_name2 == some_value2)]

hoặc là

table.query('column_name == some_value | column_name2 == some_value2')

Mã ví dụ

import pandas as pd

# Create data set
d = {'foo':[100, 111, 222], 
     'bar':[333, 444, 555]}
df = pd.DataFrame(d)

# Full dataframe:
df

# Shows:
#    bar   foo 
# 0  333   100
# 1  444   111
# 2  555   222

# Output only the row(s) in df where foo is 222:
df[df.foo == 222]

# Shows:
#    bar  foo
# 2  555  222

Trong đoạn mã trên, đây là dòng df[df.foo == 222]cung cấp các hàng dựa trên giá trị cột, 222trong trường hợp này.

Nhiều điều kiện cũng có thể:

df[(df.foo == 222) | (df.bar == 444)]
#    bar  foo
# 1  444  111
# 2  555  222

Nhưng tại thời điểm đó tôi sẽ khuyên bạn nên sử dụng hàm truy vấn , vì nó ít dài dòng hơn và mang lại kết quả tương tự:

df.query('foo == 222 | bar == 444')

5
querylà câu trả lời duy nhất ở đây tương thích với chuỗi phương thức. Có vẻ như đó là gấu trúc tương tự như filtertrong dplyr.
Berk U.

3
Xin chào, trong ví dụ thứ ba của bạn (nhiều cột) Tôi nghĩ rằng bạn cần dấu ngoặc vuông [chứ không phải dấu ngoặc tròn (ở bên ngoài.
dùng2739472

2
Lúc đầu, tôi nghĩ rằng đó |là cho AND, nhưng tất nhiên đó là toán tử OR ...
O-9

đối với nhiều điều kiện sử dụng AND, người ta có thể làmdf[condition1][condition2]
Ritwik

1
Để lại điều này ở đây chỉ trong trường hợp nó hữu ích với ai đó: từ 0,25 truy vấn có thể được sử dụng với các tên cột có khoảng trắng trong tên bằng cách đặt tên trong backticks:df.query('`my col` == 124')
cs95

65

Tôi thấy cú pháp của các câu trả lời trước là dư thừa và khó nhớ. Pandas đã giới thiệu query()phương pháp này trong v0.13 và tôi rất thích nó. Đối với câu hỏi của bạn, bạn có thể làmdf.query('col == val')

Được sao chép từ http://pandas.pydata.org/pandas-docs/version/0.17.0/indexing.html#indexing-query

In [167]: n = 10

In [168]: df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc'))

In [169]: df
Out[169]: 
          a         b         c
0  0.687704  0.582314  0.281645
1  0.250846  0.610021  0.420121
2  0.624328  0.401816  0.932146
3  0.011763  0.022921  0.244186
4  0.590198  0.325680  0.890392
5  0.598892  0.296424  0.007312
6  0.634625  0.803069  0.123872
7  0.924168  0.325076  0.303746
8  0.116822  0.364564  0.454607
9  0.986142  0.751953  0.561512

# pure python
In [170]: df[(df.a < df.b) & (df.b < df.c)]
Out[170]: 
          a         b         c
3  0.011763  0.022921  0.244186
8  0.116822  0.364564  0.454607

# query
In [171]: df.query('(a < b) & (b < c)')
Out[171]: 
          a         b         c
3  0.011763  0.022921  0.244186
8  0.116822  0.364564  0.454607

Bạn cũng có thể truy cập các biến trong môi trường bằng cách đăng ký trước @.

exclude = ('red', 'orange')
df.query('color not in @exclude')

1
Bạn chỉ cần numexprcài đặt gói .
MERose 13/03/2016

4
Trong trường hợp của tôi, tôi cần báo giá vì val là một chuỗi. df.query ('col == "val"')
smerlung

28

Linh hoạt hơn khi sử dụng .queryvới pandas >= 0.25.0:

Tháng 8 năm 2019 cập nhật câu trả lời

pandas >= 0.25.0chúng ta có thể sử dụng queryphương thức để lọc các tệp dữ liệu bằng các phương thức gấu trúc và thậm chí các tên cột có khoảng trắng. Thông thường các khoảng trắng trong tên cột sẽ báo lỗi, nhưng bây giờ chúng ta có thể giải quyết điều đó bằng cách sử dụng backtick (`) xem GitHub :

# Example dataframe
df = pd.DataFrame({'Sender email':['ex@example.com', "reply@shop.com", "buy@shop.com"]})

     Sender email
0  ex@example.com
1  reply@shop.com
2    buy@shop.com

Sử dụng .queryvới phương pháp str.endswith:

df.query('`Sender email`.str.endswith("@shop.com")')

Đầu ra

     Sender email
1  reply@shop.com
2    buy@shop.com

Ngoài ra, chúng tôi có thể sử dụng các biến cục bộ bằng cách thêm tiền tố @vào một truy vấn của chúng tôi:

domain = 'shop.com'
df.query('`Sender email`.str.endswith(@domain)')

Đầu ra

     Sender email
1  reply@shop.com
2    buy@shop.com

26

Kết quả nhanh hơn có thể đạt được bằng cách sử dụng numpy.where .

Ví dụ: với thiết lập của unubtu -

In [76]: df.iloc[np.where(df.A.values=='foo')]
Out[76]: 
     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

So sánh thời gian:

In [68]: %timeit df.iloc[np.where(df.A.values=='foo')]  # fastest
1000 loops, best of 3: 380 µs per loop

In [69]: %timeit df.loc[df['A'] == 'foo']
1000 loops, best of 3: 745 µs per loop

In [71]: %timeit df.loc[df['A'].isin(['foo'])]
1000 loops, best of 3: 562 µs per loop

In [72]: %timeit df[df.A=='foo']
1000 loops, best of 3: 796 µs per loop

In [74]: %timeit df.query('(A=="foo")')  # slowest
1000 loops, best of 3: 1.71 ms per loop

24

Đây là một ví dụ đơn giản

from pandas import DataFrame

# Create data set
d = {'Revenue':[100,111,222], 
     'Cost':[333,444,555]}
df = DataFrame(d)


# mask = Return True when the value in column "Revenue" is equal to 111
mask = df['Revenue'] == 111

print mask

# Result:
# 0    False
# 1     True
# 2    False
# Name: Revenue, dtype: bool


# Select * FROM df WHERE Revenue = 111
df[mask]

# Result:
#    Cost    Revenue
# 1  444     111

17

Để chỉ chọn các cột cụ thể trong số nhiều cột cho một giá trị nhất định trong gấu trúc:

select col_name1, col_name2 from table where column_name = some_value.

Tùy chọn:

df.loc[df['column_name'] == some_value][[col_name1, col_name2]]

hoặc là

df.query['column_name' == 'some_value'][[col_name1, col_name2]]

16

Để thêm vào câu hỏi nổi tiếng này (mặc dù hơi muộn): Bạn cũng có thể thực hiện df.groupby('column_name').get_group('column_desired_value').reset_index()để tạo khung dữ liệu mới với cột được chỉ định có giá trị cụ thể. Ví dụ

import pandas as pd
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split()})
print("Original dataframe:")
print(df)

b_is_two_dataframe = pd.DataFrame(df.groupby('B').get_group('two').reset_index()).drop('index', axis = 1) 
#NOTE: the final drop is to remove the extra index column returned by groupby object
print('Sub dataframe where B is two:')
print(b_is_two_dataframe)

Chạy cái này cho:

Original dataframe:
     A      B
0  foo    one
1  bar    one
2  foo    two
3  bar  three
4  foo    two
5  bar    two
6  foo    one
7  foo  three
Sub dataframe where B is two:
     A    B
0  foo  two
1  foo  two
2  bar  two

Câu trả lời chính xác. Chỉ muốn thêm rằng thứ hai (pd.DataFrame) là dự phòng vì get_group()sẽ tự động trả về một khung dữ liệu. Ngoài ra, bạn chỉ có thể nói "drop = True" là một tham số của reset_index(). Nói cách khác, nó có thể được rút ngắn thành: b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
Mountain Scott

7

Bạn cũng có thể sử dụng .apply:

df.apply(lambda row: row[df['B'].isin(['one','three'])])

Nó thực sự hoạt động theo hàng (nghĩa là áp dụng hàm cho từng hàng).

Đầu ra là

   A      B  C   D
0  foo    one  0   0
1  bar    one  1   2
3  bar  three  3   6
6  foo    one  6  12
7  foo  three  7  14

Kết quả giống như sử dụng như được đề cập bởi @unutbu

df[[df['B'].isin(['one','three'])]]
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.