问题描述
我正在尝试操纵索引和源数组,以便:
I'm trying to manipulate an index and source array such that:
结果[i] [j] [k] =源[i] [索引[i] [j] [k]]
我知道如何使用for循环来做到这一点,但是我使用的是巨型数组,我想使用更省时的方法.我尝试使用numpy的高级索引,但我不太了解.
I know how to do this with for loops but I'm using giant arrays and I'd like to use something more time efficient. I've tried to use numpy's advanced indexing but I don't really understand it.
示例功能:
source = [[0.0 0.1 0.2 0.3]
[1.0 1.1 1.2 1.3]
[2.0 2.1 2.2 2.3]]
indices = [[[3 1 0 1]
[3 0 0 3]]
[[0 1 0 2]
[3 2 1 1]]
[[1 1 0 1]
[0 1 2 2]]]
# result[i][j][k] = source[i][indices[i][j][k]]
result = [[[0.3 0.1 0.0 0.1]
[0.3 0.0 0.0 0.3]]
[[1.0 1.1 1.0 1.2]
[1.3 1.2 1.1 1.1]]
[[2.1 2.1 2.0 2.1]
[2.0 2.1 2.2 2.2]]]
推荐答案
使用整数高级索引的解决方案:
给出:
source = [[0.0, 0.1, 0.2, 0.3],
[1.0, 1.1, 1.2, 1.3],
[2.0, 2.1, 2.2, 2.3]]
indices = [[[3, 1, 0, 1],
[3, 0, 0, 3]],
[[0, 1, 0, 2],
[3, 2, 1, 1]],
[[1, 1, 0, 1],
[0, 1, 2, 2]]]
使用此功能:
import numpy as np
nd_source = np.array(source)
source_rows = len(source) # == 3, in above example
source_cols = len(source[0]) # == 4, in above example
row_indices = np.arange(source_rows).reshape(-1,1,1)
result = nd_source [row_indices, indices]
结果:
print (result)
[[[0.3 0.1 0. 0.1]
[0.3 0. 0. 0.3]]
[[1. 1.1 1. 1.2]
[1.3 1.2 1.1 1.1]]
[[2.1 2.1 2. 2.1]
[2. 2.1 2.2 2.2]]]
说明:
要使用Integer Advanced Indexing,关键规则是:
Explanation:
To use Integer Advanced Indexing, the key rules are:
- 我们必须提供由整数索引组成的索引数组.
- 我们必须提供尽可能多的索引数组,就像源数组中有维一样.
- 这些索引数组的形状必须相同,或者至少所有它们都可以广播为单个最终形状.
整数高级索引的工作原理是:
How the Integer Advanced Indexing works is:
鉴于源数组具有 n
个维,因此我们提供了 n
个整数索引数组:
Given that source array has n
dimensions, and that we have therefore supplied n
integer index arrays:
- 所有这些索引数组,如果不是相同的统一形状,将被广播为单一的统一形状.
- 要访问源数组中的任何元素,显然我们需要一个n元组的索引.因此,要从源数组生成结果数组,我们需要几个n元组,最终结果数组的每个元素位置都需要一个n元组.对于结果数组的每个元素位置,将从广播的索引数组中的相应元素位置构造索引的n个元组.(如上所述,请记住结果数组的形状与广播索引数组的形状完全相同).
- 因此,通过遍历遍历索引数组,我们获得了生成结果数组所需的所有n元组,其形状与广播的索引数组相同.
- All of these index arrays, if not in the same uniform shape, will be broadcasted to be in a single uniform shape.
- To access any element in the source array, we obviously need an n-tuple of indices. Therefore to generate the result array from the source array, we need several n-tuples, one n-tuple for each element-position of the final result array. For each element-position of the result array, the n-tuple of indices will be constructed from the corresponding element-positions in the broadcasted index arrays. (Remember the result array has exactly the same shape as the broadcasted index arrays, as already mentioned above).
- Thus, by traversing the index arrays in tandem, we get all the n-tuples we need to generate the result array, in the same shape as the broadcasted index arrays.
将此说明应用于上面的示例:
- 我们的源数组为
nd_source = np.array(source)
,即2d. -
我们最终的结果形状是
(3,2,4)
.
因此,我们需要提供 2
索引数组,并且这些索引数组的最终结果形状必须为(3,2,4)
,或可以广播为(3,2,4)
形状.
We therefore need to supply 2
index arrays, and these index arrays must either be in the final result shape of (3,2,4)
, or broadcastable to the (3,2,4)
shape.
我们的第一个索引数组是 row_indices = np.arange(source_rows).reshape(-1,1,1)
.( source_rows
是源中的行数,在此示例中为 3
.)此索引数组的形状为(3,1,1)
,实际上看起来像 [[[0]],[[1]],[[2]]]
.这可以广播为最终结果形状为(3,2,4)
,并且广播的数组看起来像 [[[[0,0,0,0],[0,0,0,0]],[[1,1,1,1],[1,1,1,1]],[[2,2,2,2],[2,2,2,2]]]]
.
Our first index array is row_indices = np.arange(source_rows).reshape(-1,1,1)
. (source_rows
is the number of rows in the source, which is 3
in this example) This index array has shape (3,1,1)
, and actually looks like [[[0]],[[1]],[[2]]]
. This is broadcastable to the final result shape of (3,2,4)
, and the broadcasted array looks like [[[0,0,0,0],[0,0,0,0]],[[1,1,1,1],[1,1,1,1]],[[2,2,2,2],[2,2,2,2]]]
.
我们的第二个索引数组是 indices
.尽管这不是数组,而只是列表的列表,但是当我们将其作为发送索引数组传递时,numpy足够灵活,可以自动将其转换为相应的ndarray.请注意,即使不进行任何广播,该数组也已经达到了(3,2,4)
的最终期望结果形状.
Our second index array is indices
. Though this is not an array and is only a list of lists, numpy is flexible enough to automatically convert it into the corresponding ndarray, when we pass it as our send index array. Note that this array is already in the final desired result shape of (3,2,4)
even without any broadcasting.
依次遍历这两个索引数组(一个广播数组,另一个按原样),numpy生成访问源2d数组 nd_source所需的所有2元组.
,并生成形状为(3,2,4)
的最终结果.
Traversing these two index arrays in tandem (one a broadcasted array and the other as is), numpy generates all the 2-tuples needed to access our source 2d array nd_source
, and generate the final result in the shape (3,2,4)
.
这篇关于用2D数组numpy索引3D数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!