Làm cách nào để chọn các hàng trong DataFrame giữa hai giá trị, trong Python Pandas?


99

Tôi đang cố gắng sửa đổi DataFrame dfđể chỉ chứa các hàng có giá trị trong cột closing_pricenằm trong khoảng từ 99 đến 101 và đang cố gắng thực hiện điều này với mã bên dưới.

Tuy nhiên, tôi gặp lỗi

ValueError: Giá trị sự thật của Chuỗi không rõ ràng. Sử dụng a.empty, a.bool (), a.item (), a.any () hoặc a.all ()

và tôi đang tự hỏi nếu có cách nào để làm điều này mà không cần sử dụng vòng lặp.

df = df[(99 <= df['closing_price'] <= 101)]

Vấn đề ở đây là bạn không thể so sánh một vô hướng với một mảng vì lỗi này, để so sánh bạn phải sử dụng các toán tử Bitwise và đặt chúng trong dấu ngoặc do được ưu tiên điều hành
EdChum

df.querypd.evalcó vẻ như phù hợp với trường hợp sử dụng này. Để biết thông tin về nhóm pd.eval()hàm, tính năng và trường hợp sử dụng của chúng, vui lòng truy cập Đánh giá biểu thức động ở gấu trúc bằng pd.eval () .
cs95

Câu trả lời:


103

Bạn nên sử dụng ()để nhóm vectơ boolean của mình để loại bỏ sự mơ hồ.

df = df[(df['closing_price'] >= 99) & (df['closing_price'] <= 101)]

162

Cũng hãy xem xét loạt bài giữa :

df = df[df['closing_price'].between(99, 101)]

5
Tùy chọn inclusive=Trueđược sử dụng bởi mặc định trong between, vì vậy bạn có thể truy vấn như thế nàydf = df[df['closing_price'].between(99, 101)]
Anton Ermakov

3
đây là câu trả lời tốt nhất! Bạn đã làm rất tốt!
PEBKAC 28/09/18

Có chức năng "không ở giữa" trong gấu trúc không? Tôi không tìm thấy nó.
dsugasa

2
@dsugasa, sử dụng toán tử dấu ngã với between.
Parfait

1
@dsugasa ví dụdf = df[~df['closing_price'].between(99, 101)]
33

22

có một giải pháp thay thế đẹp hơn - sử dụng phương thức query () :

In [58]: df = pd.DataFrame({'closing_price': np.random.randint(95, 105, 10)})

In [59]: df
Out[59]:
   closing_price
0            104
1             99
2             98
3             95
4            103
5            101
6            101
7             99
8             95
9             96

In [60]: df.query('99 <= closing_price <= 101')
Out[60]:
   closing_price
1             99
5            101
6            101
7             99

CẬP NHẬT: trả lời bình luận:

Tôi thích cú pháp ở đây nhưng đã rơi xuống khi cố gắng kết hợp với expresison; df.query('(mean + 2 *sd) <= closing_price <=(mean + 2 *sd)')

In [161]: qry = "(closing_price.mean() - 2*closing_price.std())" +\
     ...:       " <= closing_price <= " + \
     ...:       "(closing_price.mean() + 2*closing_price.std())"
     ...:

In [162]: df.query(qry)
Out[162]:
   closing_price
0             97
1            101
2             97
3             95
4            100
5             99
6            100
7            101
8             99
9             95

Tôi thích cú pháp ở đây nhưng đã rơi xuống khi cố gắng kết hợp với expresison; df.query ( '(bình + 2 * sd) <= closing_price <= (trung bình + 2 * sd)')
lập bản đồ dom

1
@mappingdom, là gì meanvà là sdgì? Đó có phải là những tên cột không?
MaxU

không có họ là những độ lệch trung bình và tiêu chuẩn tính toán được lưu trữ như một phao
dom lập bản đồ

@mappingdom, ý bạn nói "được lưu trữ" là gì?
MaxU

@mappingdom, tôi đã cập nhật bài đăng của mình - đó có phải là những gì bạn đang yêu cầu không?
MaxU

9

bạn cũng có thể sử dụng .between()phương pháp

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")

emp[emp["Salary"].between(60000, 61000)]

Đầu ra

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


6
newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

hoặc là

mean = closing_price.mean()
std = closing_price.std()

newdf = df.query('@mean <= closing_price <= @std')

3

Nếu bạn đang xử lý nhiều giá trị và nhiều đầu vào, bạn cũng có thể thiết lập một hàm áp dụng như thế này. Trong trường hợp này, lọc khung dữ liệu cho các vị trí GPS nằm trong phạm vi nhất định.

def filter_values(lat,lon):
    if abs(lat - 33.77) < .01 and abs(lon - -118.16) < .01:
        return True
    elif abs(lat - 37.79) < .01 and abs(lon - -122.39) < .01:
        return True
    else:
        return False


df = df[df.apply(lambda x: filter_values(x['lat'],x['lon']),axis=1)]

1

Thay vì điều này

df = df[(99 <= df['closing_price'] <= 101)]

Bạn nên sử dụng cái này

df = df[(df['closing_price']>=99 ) & (df['closing_price']<=101)]

Chúng ta phải sử dụng các toán tử Logic bitwise của NumPy |, &, ~, ^ cho các truy vấn ghép. Ngoài ra, dấu ngoặc đơn cũng quan trọng đối với quyền ưu tiên của toán tử.

Để biết thêm thông tin, bạn có thể truy cập liên kết: So sánh, Mặt nạ và Boolean Logic

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.