英文:
Numpy: Performing in-place operation along moving axis
问题
Here is the translation of the code portion you provided:
好的,我尽力在标题中描述我的问题。
我的问题如下:
我有一个numpy数组,它的形状/维度可能不总是一致的(范围从1到3)。以最简单的情况,当数组的形状为[100]时,我可以执行以下操作(并获得所需的结果):
```python
for i, bounds in enumerate(values):
low, high = bounds
arr[i] *= high - low
当数组的形状为[100, 200]时,我可以执行以下操作:
for i, bounds in enumerate(values):
low, high = bounds
arr[i, :] *= high - low
或者如果数组的形状为[200, 100],我可以执行以下操作:
for i, bounds in enumerate(values):
low, high = bounds
arr[:, i] *= high - low
而在3D情况下,如果数组的形状为[300, 100, 200],我会这样做:
for i, bounds in enumerate(values):
low, high = bounds
arr[:, i, :] *= high - low
我的问题是,我不知道如何改变i
在索引中的位置,或者如何在迭代与i
对应的轴上索引所有元素(当arr
的形状正在改变时)。在我的示例中,i
的“位置”是基于数组形状中100
的位置。这是NumPy可以做到的吗,还是我必须使用多个if语句?
<details>
<summary>英文:</summary>
Ok I did my best to describe my problem in the title.
My problem is as follows:
I have a numpy array which may not always have a consistent shape/dimension (ranges from 1 to 3). Taking the simplest case when the array is of shape [100], I can perform the following (and obtain the desired result):
for i, bounds in enumerate(values):
low, high = bounds
arr[i] *= high - low
when the array is of shape [100, 200], I can do the following:
for i, bounds in enumerate(values):
low, high = bounds
arr[i, :] *= high - low
or if the array is of shape [200, 100], I can instead do:
for i, bounds in enumerate(values):
low, high = bounds
arr[:, i] *= high - low
and in the 3d case if the array is of shape [300, 100, 200], I would do:
for i, bounds in enumerate(values):
low, high = bounds
arr[:, i, :] *= high - low
My problem is I don't know how to alter the position of `i` in the index or how to index all the elements when iterating over the axis that corresponds to `i` (when the shape of `arr` is changing). In my example, the "location" of `i` is based on where `100` falls in the shape of the array. Is this something numpy can do or am I stuck with a number of if statements?
</details>
# 答案1
**得分**: 2
有一种可能性是将轴移动,以将您想要的轴(根据您的标准)放在新视图 `a2` 中的第一个位置。然后,`a2[i,:,:]` 就等同于 `arr[:,i,:]`(例如),如果正确的轴是1。此外,通过这种方式,您可以使用 `...` 表示法来替代所有的 `:`。所以 `a2[i,...]`。
```python
# 将大小为100的轴移动到第一个位置(索引0)在a2视图中
# (a2是arr的视图。因此,修改其内容会更改arr的内容)。
# 请注意,如果第一个轴已经是大小为100,则不会发生任何变化
a2 = np.moveaxis(arr, arr.shape.index(100), 0)
for i, (low, high) in enumerate(values):
a2[i, ...] *= high - low
# 请注意,这个 `...` 在任何维度上都可以工作,甚至是1。
英文:
One possibility is to move the axis to put the axis you want (according to your criterion) first, in a new view a2
. Then a2[i,:,:]
is the same as arr[:,i,:]
(for example) if the correct axis was 1. Plus, that way, you can use ...
notation, to replace all the :
. So a2[i,...]
.
# Move axis whose size is 100 in 1st position (index 0) in a2 view
# (a2 is a view of arr. So modifying its contents change arr content).
# Note, if the 1st axis is already of size 100 this will do nothing
a2 = np.moveaxis(arr, arr.shape.index(100), 0)
for i, (low, high) in enumerate(values):
a2[i, ...] *= high - low
# Note this `...` works whatever the dimension, even 1.
答案2
得分: 1
你可以动态创建索引。索引集合是一个元组,:
对应 slice(None)
。
找到与值的长度相同的维度中的索引。然后在循环中更新索引列表中的该索引。
indexes = [slice(None)] * arr.ndims
variable_pos = arr.shape.index(len(values))
for i, (low, high) in enumerate(values):
indexes[variable_pos] = i
arr[tuple(indexes)] *= high - low
英文:
You can create the indexes dynamically. The set of indexes is a tuple, and :
is slice(None)
.
Find the index in the dimensions that's the same as the length of values. Then update that index in the list of index list in the loop.
indexes = [slice(None)] * arr.ndims
variable_pos = arr.shape.index(len(values))
for i, (low, high) in enumerate(values):
indexes[variable_pos] = i
arr[tuple(indexes)] *= high - low
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论