tôi nhận được một lỗi khác so với bạn làm (sử dụng 1.7.0.dev NumPy):
ValueError: setting an array element with a sequence.
nên giải thích dưới đây có thể không được chính xác cho hệ thống của bạn (hoặc thậm chí nó có thể là sai giải thích cho những gì tôi thấy).
Đầu tiên, hãy chú ý rằng chỉ mục liên tiếp của một structured array mang đến cho bạn một đối tượng numpy.void
(xem data type docs)
import numpy as np
dt = np.dtype([('tuple', (int, 2))])
a = np.zeros(3, dt)
print type(a[0]) # = numpy.void
Từ những gì tôi hiểu, void
là loại giống như một danh sách Python vì nó có thể giữ các đối tượng khác nhau các kiểu dữ liệu, có ý nghĩa vì các cột trong một mảng có cấu trúc có thể là các kiểu dữ liệu khác nhau.
Nếu, thay vì lập chỉ mục, bạn cắt ra hàng đầu tiên, bạn nhận được một ndarray
:
print type(a[:1]) # = numpy.ndarray
Điều này giống như cách danh sách Python làm việc:
b = [1, 2, 3]
print b[0] # 1
print b[:1] # [1]
Cắt lát trả về một phiên bản rút gọn của chuỗi gốc, nhưng việc lập chỉ mục trả về một phần tử (ở đây, một số int
; ở trên, loại void
).
Vì vậy, khi bạn cắt thành các hàng của mảng có cấu trúc, bạn sẽ mong đợi nó hoạt động giống như mảng ban đầu của bạn (chỉ với ít hàng hơn). Tiếp tục với ví dụ của bạn, bây giờ bạn có thể gán cho các 'tuple' cột của hàng đầu tiên:
a[:1]['tuple'] = (1, 2)
Vì vậy, ... tại sao không a[0]['tuple'] = (1, 2)
làm việc?
Vâng, hãy nhớ rằng a[0]
trả về đối tượng void
. Vì vậy, khi bạn gọi
a[0]['tuple'] = (1, 2) # this line fails
bạn đang gán một tuple
tới phần tử 'tuple' của đối tượng void
. Lưu ý: mặc dù thực tế bạn đã gọi chỉ số này 'tuple', nó được lưu trữ dưới dạng ndarray
:
print type(a[0]['tuple']) # = numpy.ndarray
Vì vậy, điều này có nghĩa các tuple cần mà bị quăng vào một ndarray
. Nhưng, đối tượng void
không thể truyền bài tập (đây chỉ là phỏng đoán) vì nó có thể chứa các loại dữ liệu tùy ý nên không biết loại nào sẽ truyền.Để giải quyết vấn đề này, bạn có thể tự mình nhập dữ liệu vào:
a[0]['tuple'] = np.array((1, 2))
Thực tế là chúng tôi gặp phải lỗi trên cho bạn vì không truyền địa chỉ lỗi mà tôi nhận được --- không phải địa chỉ bạn nhận được .
Phụ Lục:
Vậy tại sao các công việc sau đây?
a[0]['tuple'][:] = (1, 2)
Ở đây, bạn đang lập chỉ mục vào mảng đó khi bạn thêm [:]
, nhưng không có điều đó, bạn đang lập chỉ mục vào đối tượng void
. Nói cách khác, a[0]['tuple'][:]
nói "thay thế các phần tử của mảng được lưu trữ" (được xử lý bởi mảng), a[0]['tuple']
nói "thay thế mảng đã lưu trữ" (được xử lý bởi void
).
Epilogue:
Lạ lùng thay, tiếp cận hàng (ví dụ: lập chỉ mục với 0) dường như thả các mảng cơ sở, nhưng nó vẫn cho phép bạn gán cho mảng cơ sở.
print a['tuple'].base is a # = True
print a[0].base is a # = False
a[0] = ((1, 2),) # `a` is changed
lẽ void
là không thực sự một mảng vì vậy nó không có một mảng cơ sở, ... nhưng sau đó tại sao nó có một thuộc tính base
?
Mẹo: khi đăng mã lên SO, vui lòng đăng bit chúng tôi có thể cắt và dán; trong trường hợp của Python, điều đó có nghĩa là sử dụng '#' cho các chú thích được chèn vào, không phải '%'. – DSM
Những thứ vui nhộn, tôi cũng thấy điều này cho kết quả tương tự theo cách sử dụng 1.6.1 ... –
Một chút lẻ, nhưng 'a [0] ['tuple'] [:] = (1,2)' hoạt động, có thể có một đầu mối ở đó ... –