Đây là một cách tiếp cận khác. Nó sạch hơn, hiệu quả hơn và có lợi thế là columns
có thể trống (trong trường hợp đó toàn bộ khung dữ liệu được trả về).
def filter(df, value, *columns):
return df.loc[df.loc[:, columns].eq(value).all(axis=1)]
Giải thích
values = df.loc[:, columns]
chọn chỉ có các cột chúng ta quan tâm.
masks = values.eq(value)
đưa ra một khung dữ liệu boolean chỉ ra sự bình đẳng với các giá trị mục tiêu.
mask = masks.all(axis=1)
áp dụng AND trên các cột (trả về mặt nạ chỉ mục). Lưu ý rằng bạn có thể sử dụng masks.any(axis=1)
cho OR.
return df.loc[mask]
áp dụng mặt nạ chỉ mục cho khung dữ liệu.
Demo
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0, 2, (100, 3)), columns=list('ABC'))
# both columns
assert np.all(filter(df, 1, 'A', 'B') == df[(df.A == 1) & (df.B == 1)])
# no columns
assert np.all(filter(df, 1) == df)
# different values per column
assert np.all(filter(df, [1, 0], 'A', 'B') == df[(df.A == 1) & (df.B == 0)])
Alternative
Đối với một số lượng nhỏ các cột (< 5), các giải pháp sau đây, dựa trên steven's answer, nhiều performant hơn ở trên, mặc dù ít linh hoạt hơn. Như là, nó sẽ không hoạt động cho một tập hợp rỗng columns
và sẽ không hoạt động bằng cách sử dụng các giá trị khác nhau cho mỗi cột.
from operator import and_
def filter(df, value, *columns):
return df.loc[reduce(and_, (df[column] == value for column in columns))]
Lấy ra một đối tượng Series
bằng phím (df[column]
) là nhanh hơn so với việc xây dựng một đối tượng DataFrame
xung quanh một tập hợp con của các cột (df.loc[:, columns]
) đáng kể.
In [4]: %timeit df['A'] == 1
100 loops, best of 3: 17.3 ms per loop
In [5]: %timeit df.loc[:, ['A']] == 1
10 loops, best of 3: 48.6 ms per loop
Tuy nhiên, việc tăng tốc này trở nên không đáng kể khi xử lý nhiều cột hơn. Các nút cổ chai trở thành ANDing các mặt nạ với nhau, trong đó reduce(and_, ...)
là chậm hơn so với Pandas được xây dựng all(axis=1)
.
Có thể dupe: https://stackoverflow.com/questions/11869910/pandas-filter-rows-of-dataframe-with-operator-chaining – chishaku
https://stackoverflow.com/questions/13611065/efficient-way- to-apply-multiple-filters-to-pandas-dataframe-hoặc-series – chishaku
Bạn luôn muốn so sánh các cột khác nhau có cùng giá trị không? (1 trong trường hợp này?) – joris