2015-03-04 17 views
8

Indexing một mảng NumPy với nhau - cả hai đều được định nghĩa là dtype = 'uint32'. Sử dụng numpy.take để lập chỉ mục và nhận được lỗi truyền không an toàn. Không đi qua điều này trước đây. Bất cứ ý tưởng những gì đang xảy ra?NumPy đúc mảng cai trị không phải là 'an toàn'

Python 2.7.8 |Anaconda 2.1.0 (32-bit)| (default, Jul 2 2014, 15:13:35) [MSC v.1500 32 bit (Intel)] on win32 
Type "copyright", "credits" or "license()" for more information. 

>>> import numpy 
>>> numpy.__version__ 
'1.9.0' 

>>> a = numpy.array([9, 7, 5, 4, 3, 1], dtype=numpy.uint32) 
>>> b = numpy.array([1, 3], dtype=numpy.uint32) 
>>> c = a.take(b) 

Traceback (most recent call last): 
    File "<pyshell#12>", line 1, in <module> 
    c = a.take(b) 
TypeError: Cannot cast array data from dtype('uint32') to dtype('int32') according to the rule 'safe' 
+0

Tôi không nhận được cảnh báo nào khi chạy python 3.4.3 64-bit và numpy '1.9.2rc1' – EdChum

+0

Tôi nghĩ vấn đề là gán 'a.take (b)' cho 'c'. Hãy thử thiết lập 'c = numpy.array (0, dtype = numpy.uint32)' trước 'c = a.take (b)' –

+0

Không có cảnh báo nào ở đây với Python 2.7.5 64-bit và numpy 1.9.1. – Carsten

Trả lời

7

này khá phổ biến khi làm việc chức năng NumPy đòi hỏi chỉ số hoặc độ dài được xác định (nó không chỉ take, xem ví dụ here).

Vấn đề là, cho các mục đích lập chỉ mục, NumPy muốn đối xử với mảng uint32 của bạn như là một mảng int32 (mà có lẽ là "con trỏ" kiểu số nguyên trên hệ thống 32-bit của bạn, np.intp) và muốn quăng nó xuống loại đó.

Nó không thể làm điều này một cách an toàn - một số các số nguyên trong một mảng unsigned có thể không được biểu diễn như một chút nguyên ký 32. Lỗi bạn thấy phản ánh điều này.

Điều này có nghĩa là bạn sẽ nhận được cùng một lỗi nếu b có dtype int64 hoặc kiểu chữ nổi, nhưng không phải nếu đó là int32 hoặc dtype số nguyên nhỏ hơn.

Đối với giá trị của nó, đây không phải là vấn đề tức thời đối với ký hiệu lập chỉ mục a[b] cho phép truyền không an toàn (nhưng sẽ gây ra lỗi nếu chỉ mục vượt quá giới hạn). Hãy thử ví dụ a[2**31] - NumPy phôi thành int32 nhưng sau đó than phiền rằng chỉ mục -2147483648 nằm ngoài giới hạn.

+0

Xin cảm ơn! Tôi thường sử dụng [b] nhưng điều đó được cho là chậm hơn .take. Dù sao, sẽ dính vào những gì làm việc! –

+0

Nó không còn chậm hơn nữa trong phiên bản 1.9.x. Và hành vi này có lẽ nên được báo cáo dưới dạng lỗi, 'np.take' sẽ thực hiện tương tự như việc lập chỉ mục: sử dụng tính năng truyền không an toàn khi nó đã xác nhận rằng chỉ mục là một số nguyên, ví dụ: trên một hệ thống 32 bit 'a [2 ** 32-1]' trả về 'a [-1]', bởi vì '2 ** 32-1' được chuyển thành một' np.uint32' mà sau đó không được đúc thành một 'np.int32'. Hành vi lỗi trong trường hợp góc này ít gây khó chịu hơn làm cho 'np.uint32' không thể sử dụng làm chỉ mục. – Jaime

+0

@Jaime Rất vui khi biết rằng kiểu lập chỉ mục không còn chậm. Tôi sẽ thả một ghi chú vào danh sách gửi thư numpy về np.take. Cảm ơn! –

Các vấn đề liên quan