112

Giả sử tôi có một mảng NumPy x = [5, 2, 3, 1, 4, 5], y = ['f', 'o', 'o', 'b', 'a', 'r']. Tôi muốn chọn các phần tử ytương ứng với các phần tử xlớn hơn 1 và nhỏ hơn 5.

Tôi đã thử

x = array([5, 2, 3, 1, 4, 5])
y = array(['f','o','o','b','a','r'])
output = y[x > 1 & x < 5] # desired output is ['o','o','a']

nhưng điều này không làm việc. Làm thế nào tôi có thể làm điều này?

|
174

Biểu thức của bạn hoạt động nếu bạn thêm dấu ngoặc đơn:

>>> y[(1 < x) & (x < 5)]
array(['o', 'o', 'a'], 
      dtype='|S1')
|
  • 1

    Điều đó thật tuyệt .. vecMask = 1 <x tạo ra mặt nạ vector như vecMask = (Sai, Đúng, ...), có thể được kết hợp với các mặt nạ vector khác. Mỗi phần tử là điều kiện để lấy các phần tử của vectơ nguồn (Đúng) hoặc không (Sai). Điều này cũng có thể được sử dụng với phiên bản đầy đủ numpy.extract (vecMask, vecSrc) hoặc numpy.where (vecMask, vecSrc, vecSrc2).

    – Hồ Phương Tâm 17:08:18 03/11/2016
  • 1

    ồ điều này thật kỳ lạ

    – Bùi Kiều Ngân 16:54:19 27/05/2017
  • 1

    @JennyYueJin: Nó xảy ra vì sự ưu tiên. (Bitwise) &có độ ưu tiên cao hơn <>, do đó có độ ưu tiên cao hơn (logic) and. x > 1 and x < 5trước hết là tạo ra sự bất bình đẳng và sau đó là sự kết hợp logic; x > 1 & x < 5đánh giá kết hợp bitwise của 1và (các giá trị trong) x, sau đó là bất đẳng thức. (x > 1) & (x < 5)buộc các bất đẳng thức phải đánh giá trước, vì vậy tất cả các hoạt động xảy ra theo thứ tự dự định và kết quả đều được xác định rõ. Xem tài liệu ở đây.

    – Lý Ngọc Tùng 17:58:41 16/11/2017
  • 1

    @ ru111 Nó cũng hoạt động trên Python 3.6 (không có lý do gì để nó ngừng hoạt động).

    – Đặng Thắng Cảnh 20:13:00 07/12/2017
  • 1

    Tôi nhận được "ValueError: Giá trị thật của một mảng có nhiều phần tử là mơ hồ. Sử dụng a.any () hoặc a.all ()"

    – Hoàng Hán Lâm 20:15:37 07/12/2017
29

IMO OP không thực sự muốn np.bitwise_and()(aka &) nhưng thực sự muốn np.logical_and()vì họ đang so sánh các giá trị logic như TrueFalse- xem bài đăng SO này trên logic so với bitwise để thấy sự khác biệt.

>>> x = array([5, 2, 3, 1, 4, 5])
>>> y = array(['f','o','o','b','a','r'])
>>> output = y[np.logical_and(x > 1, x < 5)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')

Và cách tương đương để làm điều này là bằng np.all()cách thiết lập axisđối số một cách thích hợp.

>>> output = y[np.all([x > 1, x < 5], axis=0)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')

Bởi các con số:

>>> %timeit (a < b) & (b < c)
The slowest run took 32.97 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.15 µs per loop

>>> %timeit np.logical_and(a < b, b < c)
The slowest run took 32.59 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.17 µs per loop

>>> %timeit np.all([a < b, b < c], 0)
The slowest run took 67.47 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.06 µs per loop

vì vậy sử dụng np.all()là chậm, nhưng &logical_andkhoảng giống nhau.

|
  • 1

    Bạn cần cẩn thận một chút về cách bạn nói về những gì được đánh giá. Ví dụ, trong output = y[np.logical_and(x > 1, x < 5)], x < 5 được đánh giá (có thể tạo ra một mảng khổng lồ), mặc dù đó là đối số thứ hai, bởi vì đánh giá đó xảy ra bên ngoài hàm. IOW, logical_andđược thông qua hai đối số đã được đánh giá. Điều này khác với trường hợp thông thường a and b, trong đó bkhông được đánh giá nếu alà truelike.

    – Hồ Minh Khánh 19:29:43 05/09/2013
  • 1

    không có sự khác biệt giữa bitwise_and () và logic_and () cho các mảng boolean

    – Lý Thanh Uyên 20:07:12 13/04/2014
18

Thêm một chi tiết vào câu trả lời của @JF Sebastian và @Mark Mikofski:
Nếu một người muốn có được các chỉ số tương ứng (thay vì các giá trị thực của mảng), đoạn mã sau sẽ thực hiện:

Để đáp ứng nhiều điều kiện (tất cả):

select_indices = np.where( np.logical_and( x > 1, x < 5) )[0] #   1 < x <5

Để đáp ứng nhiều điều kiện (hoặc):

select_indices = np.where( np.logical_or( x < 1, x > 5 ) )[0] # x <1 or x >5
|
  • 1

    Lưu ý rằng numpy.where sẽ không chỉ trả về một mảng các chỉ mục, mà thay vào đó sẽ trả về một tuple (đầu ra của condition.nonzero ()) chứa các mảng - trong trường hợp này (the array of indices you want,), vì vậy bạn sẽ cần select_indices = np.where(...)[0]nhận được kết quả bạn muốn và mong đợi.

    – Vũ Tường Vy 18:11:20 16/11/2017
5

Tôi thích sử dụng np.vectorizecho các nhiệm vụ như vậy. Hãy xem xét những điều sau đây:

>>> # Arrays
>>> x = np.array([5, 2, 3, 1, 4, 5])
>>> y = np.array(['f','o','o','b','a','r'])

>>> # Function containing the constraints
>>> func = np.vectorize(lambda t: t>1 and t<5)

>>> # Call function on x
>>> y[func(x)]
>>> array(['o', 'o', 'a'], dtype='<U1')

Ưu điểm là bạn có thể thêm nhiều loại ràng buộc hơn trong hàm vectơ.

Hy vọng nó giúp.

|
1

Thật ra tôi sẽ làm theo cách này:

L1 là danh sách chỉ mục của các yếu tố thỏa mãn điều kiện 1; (có thể bạn có thể sử dụng somelist.index(condition1)hoặc np.where(condition1)để lấy L1.)

Tương tự, bạn nhận được L2, một danh sách các yếu tố thỏa mãn điều kiện 2;

Sau đó, bạn tìm thấy giao lộ bằng cách sử dụng intersect(L1,L2).

Bạn cũng có thể tìm thấy giao điểm của nhiều danh sách nếu bạn có nhiều điều kiện để đáp ứng.

Sau đó, bạn có thể áp dụng chỉ mục trong bất kỳ mảng nào khác, ví dụ: x.

|
0

Đối với mảng 2D, bạn có thể làm điều này. Tạo mặt nạ 2D bằng điều kiện. Kiểu chữ mặt nạ điều kiện thành int hoặc float, tùy thuộc vào mảng và nhân nó với mảng ban đầu.

In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.