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])
Vấn đề là bạn vẫn không thể sử dụng d.mean(), d.flatten() v.v. – episodeyang