2010-08-02 39 views

Trả lời

17

Trong khi NumPy biết về mảng các đối tượng tùy ý, nó tối ưu hóa cho các mảng đồng nhất các số với kích thước cố định. Nếu bạn thực sự cần mảng mảng, tốt hơn hãy sử dụng danh sách lồng nhau. Nhưng tùy thuộc vào mục đích sử dụng dữ liệu của bạn, các cấu trúc dữ liệu khác nhau có thể còn tốt hơn, ví dụ: một mảng bị che khuất nếu bạn có một số điểm dữ liệu không hợp lệ.

Nếu bạn thực sự muốn mảng NumPy linh hoạt, sử dụng một cái gì đó như thế này:

numpy.array([[0,1,2,3], [2,3,4]], dtype=object) 

Tuy nhiên điều này sẽ tạo ra một mảng một chiều mà các cửa hàng tham chiếu đến các danh sách, có nghĩa là bạn sẽ mất hầu hết những lợi ích của Numpy (xử lý vectơ, địa phương, cắt, vv).

12

Điều này không được hỗ trợ tốt trong Numpy (theo định nghĩa, hầu như ở khắp mọi nơi, một "mảng hai chiều" có tất cả các hàng có chiều dài bằng nhau). Một danh sách Python của mảng NumPy có thể là một giải pháp tốt cho bạn, như cách này bạn sẽ nhận được những ưu điểm của NumPy nơi bạn có thể sử dụng chúng:

cells = [numpy.array(a) for a in [[0,1,2,3], [2,3,4]]] 
12

Chúng tôi đang gần 7 năm sau khi câu hỏi được hỏi, và mã của bạn

cells = numpy.array([[0,1,2,3], [2,3,4]]) 

thực hiện trong numPy 1.12.0, python 3.5, không tạo ra bất kỳ lỗi và cells chứa:

array([[0, 1, 2, 3], [2, 3, 4]], dtype=object) 

bạn truy cập của bạn cells thành phần là cells[0][2] # (=2).

Một thay thế cho giải pháp tom10 nếu bạn muốn xây dựng danh sách các mảng NumPy khi đang bay như các yếu tố mới (tức là mảng) trở nên có sẵn là sử dụng append:

d = []     # initialize an empty list 
a = np.arange(3)  # array([0, 1, 2]) 
d.append(a)   # [array([0, 1, 2])] 
b = np.arange(3,-1,-1) #array([3, 2, 1, 0]) 
d.append(b)   #[array([0, 1, 2]), array([3, 2, 1, 0])] 
+0

Vấn đề là bạn vẫn không thể sử dụng d.mean(), d.flatten() v.v. – episodeyang

1

Một lựa chọn khác sẽ được lưu trữ của bạn mảng là một mảng liền kề và cũng lưu trữ kích thước hoặc bù của chúng. Điều này có một chút suy nghĩ khái niệm hơn về cách hoạt động trên mảng của bạn, nhưng một số lượng lớn đáng ngạc nhiên của các hoạt động có thể được thực hiện để làm việc như thể bạn có một mảng hai chiều với các kích cỡ khác nhau. Trong trường hợp không thể, thì có thể sử dụng np.split để tạo danh sách mà calocedrus đề xuất. Các hoạt động đơn giản nhất là ufuncs, bởi vì chúng yêu cầu hầu như không có sửa đổi. Dưới đây là một số ví dụ:

cells_flat = numpy.array([0, 1, 2, 3, 2, 3, 4]) 
# One of these is required, it's pretty easy to convert between them, 
# but having both makes the examples easy 
cell_lengths = numpy.array([4, 3]) 
cell_starts = numpy.insert(cell_lengths[:-1].cumsum(), 0, 0) 
cell_lengths2 = numpy.diff(numpy.append(cell_starts, cells_flat.size)) 
assert np.all(cell_lengths == cell_lengths2) 

# Copy prevents shared memory 
cells = numpy.split(cells_flat.copy(), cell_starts[1:]) 
# [array([0, 1, 2, 3]), array([2, 3, 4])] 

numpy.array([x.sum() for x in cells]) 
# array([6, 9]) 
numpy.add.reduceat(cells_flat, cell_starts) 
# array([6, 9]) 

[a + v for a, v in zip(cells, [1, 3])] 
# [array([1, 2, 3, 4]), array([5, 6, 7])] 
cells_flat + numpy.repeat([1, 3], cell_lengths) 
# array([1, 2, 3, 4, 5, 6, 7]) 

[a.astype(float)/a.sum() for a in cells] 
# [array([ 0.  , 0.16666667, 0.33333333, 0.5  ]), 
# array([ 0.22222222, 0.33333333, 0.44444444])] 
cells_flat.astype(float)/np.add.reduceat(cells_flat, cell_starts).repeat(cell_lengths) 
# array([ 0.  , 0.16666667, 0.33333333, 0.5  , 0.22222222, 
#   0.33333333, 0.44444444]) 

def complex_modify(array): 
    """Some complicated function that modifies array 

    pretend this is more complex than it is""" 
    array *= 3 

for arr in cells: 
    complex_modify(arr) 
cells 
# [array([0, 3, 6, 9]), array([ 6, 9, 12])] 
for arr in numpy.split(cells_flat, cell_starts[1:]): 
    complex_modify(arr) 
cells_flat 
# array([ 0, 3, 6, 9, 6, 9, 12]) 
Các vấn đề liên quan