gpt4 book ai didi

python - 使用 python 中数组的索引切片二维数组

转载 作者:行者123 更新时间:2023-11-28 17:42:44 25 4
gpt4 key购买 nike

我正在处理 2D numpy 数组的切片。为了选择切片,我将索引存储在数组中。例如,我有:

mat = np.zeros([xdim,ydim], float)
xmin = np.array([...]) # Array of minimum indices in x
xmax = np.array([...]) # Array of maximum indices in x
ymin = np.array([...]) # Array of minimum indices in y
ymax = np.array([...]) # Array of maximum indices in y
value = np.array([...]) # Values

其中 ... 只是表示之前计算的一些整数。所有数组都定义明确,长度约为 265000。我想做的是这样的:

mat[xmin:xmax, ymin:ymax] += value

以这样的方式,对于第一个元素,我将拥有:

mat[xmin[0]:xmax[0], ymin[0]:ymax[0]] += value[0]
mat[xmin[1]:xmax[1], ymin[1]:ymax[1]] += value[1]

等等,对于数组的 ~265000 个元素。不幸的是,我刚刚写的没有用,它抛出错误:IndexError: invalid slice

我一直在尝试按照此处的建议使用 np.meshgrid:NumPy: use 2D index array from argmin in a 3D slice ,但它还没有为我工作。此外,我正在寻找一种 pythonic 方式来避免 for 循环。

任何帮助将不胜感激!

谢谢!

最佳答案

我认为如果不借助 Cython 或类似工具,就没有令人满意的方法来矢量化您的问题。让我概述一下纯 numpy 解决方案的样子,这应该清楚说明为什么这可能不是一个很好的方法。

首先,让我们看一个 1D 案例。在 numpy 中使用一堆切片无能为力,因此首要任务是将它们扩展为单独的索引。假设您的阵列是:

mat = np.zeros((10,))
x_min = np.array([2, 5, 3, 1])
x_max = np.array([5, 9, 8, 7])
value = np.array([0.2, 0.6, 0.1, 0.9])

然后以下代码将切片限制扩展为(可能重复的)索引和值的列表,将它们与 bincount 连接在一起,并将它们添加到原始 mat:

x_len = x_max - x_min
x_cum_len = np.cumsum(x_len)
x_idx = np.arange(x_cum_len[-1])
x_idx[x_len[0]:] -= np.repeat(x_cum_len[:-1], x_len[1:])
x_idx += np.repeat(x_min, x_len)
x_val = np.repeat(value, x_len)
x_cumval = np.bincount(x_idx, weights=x_val)
mat[:len(x_cumval)] += x_cumval

>>> mat
array([ 0. , 0.9, 1.1, 1.2, 1.2, 1.6, 1.6, 0.7, 0.6, 0. ])

可以将其扩展到您的 2D 案例,尽管它一点也不微不足道,而且事情开始变得难以理解:

mat = np.zeros((10, 10))
x_min = np.array([2, 5, 3, 1])
x_max = np.array([5, 9, 8, 7])
y_min = np.array([1, 7, 2, 6])
y_max = np.array([6, 8, 6, 9])
value = np.array([0.2, 0.6, 0.1, 0.9])

x_len = x_max - x_min
y_len = y_max - y_min
total_len = x_len * y_len
x_cum_len = np.cumsum(x_len)
x_idx = np.arange(x_cum_len[-1])
x_idx[x_len[0]:] -= np.repeat(x_cum_len[:-1], x_len[1:])
x_idx += np.repeat(x_min, x_len)
x_val = np.repeat(value, x_len)
y_min_ = np.repeat(y_min, x_len)
y_len_ = np.repeat(y_len, x_len)
y_cum_len = np.cumsum(y_len_)
y_idx = np.arange(y_cum_len[-1])
y_idx[y_len_[0]:] -= np.repeat(y_cum_len[:-1], y_len_[1:])
y_idx += np.repeat(y_min_, y_len_)
x_idx_ = np.repeat(x_idx, y_len_)
xy_val = np.repeat(x_val, y_len_)
xy_idx = np.ravel_multi_index((x_idx_, y_idx), dims=mat.shape)
xy_cumval = np.bincount(xy_idx, weights=xy_val)
mat.ravel()[:len(xy_cumval)] += xy_cumval

产生:

>>> mat
array([[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0.9, 0.9, 0.9, 0. ],
[ 0. , 0.2, 0.2, 0.2, 0.2, 0.2, 0.9, 0.9, 0.9, 0. ],
[ 0. , 0.2, 0.3, 0.3, 0.3, 0.3, 0.9, 0.9, 0.9, 0. ],
[ 0. , 0.2, 0.3, 0.3, 0.3, 0.3, 0.9, 0.9, 0.9, 0. ],
[ 0. , 0. , 0.1, 0.1, 0.1, 0.1, 0.9, 1.5, 0.9, 0. ],
[ 0. , 0. , 0.1, 0.1, 0.1, 0.1, 0.9, 1.5, 0.9, 0. ],
[ 0. , 0. , 0.1, 0.1, 0.1, 0.1, 0. , 0.6, 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.6, 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ]])

但是如果您有 265,000 个任意大小的二维切片,那么索引数组将非常快地进入数百万个项目。必须处理如此多的数据读写可能会抵消使用 numpy 带来的速度提升。坦率地说,我怀疑这根本不是一个好选择,因为您的代码将变得多么神秘。

关于python - 使用 python 中数组的索引切片二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22138855/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com