Numpy off-anti-diagonal fancy indexing.

huangapple go评论64阅读模式
英文:

Numpy off-anti-diagonal fancy indexing

问题

以下是翻译好的部分:

这些花式索引指向矩阵的非对角线元素。元素之间的步幅也是固定的。是否有一种方法可以使用基本索引而不是花式索引来实现相同的 target(以便返回的数组不拥有数据并且不是内存连续的),同时仍然具有可读性的代码?

英文:

Is it possible to convert the following fancy indexing to basic indexing using NumPy slices?

import numpy as np
fancy_indices = np.arange(10), 18 - np.arange(10)
source = np.arange(400).reshape(20, 20)
 
target = source[fancy_indices] 

These fancy indices are pointing to off-anti-diagonal elements of the matrix. The stride step between elements is also fixed. Is there a way to use basic indexing, as opposed to fancy indexing, to achieve the same target (so that the returned array does not own data and is not memory contiguous), whilst still having readable code?

答案1

得分: 1

ressourceview,但是它是只读的:

In [54]: source[0,18]=1000
In [55]: res
Out[55]: array([1000,   37,   56,   75,   94,  113,  132,  151,  170,  189])

In [56]: res[0]=18
---------------------------------------------------------------------------
ValueError: assignment destination is read-only

查看 np.diag 的代码,我们发现它使用了 arr.flat 索引。因此,我们可以直接使用以下方式获取目标:

In [59]: source.flat[18:190:19]
Out[59]: array([1000,   37,   56,   75,   94,  113,  132,  151,  170,  189])

但是这个方式不是一个 view

np.diagonal 文档中提到了只读视图的部分。还演示了反对角线的用法。如果给定一个2D数组,np.diag 使用 np.diagonalarr.diagonal 是编译的,但 np.diag 使用 flat 技巧来创建对角线矩阵。

在评论中,我提到了使用 as_strided。这种方法获取了10个反对角线元素,但是从19开始,而不是从18开始。但是对于这个目的,使用 flat 更容易:

In [80]: np.lib.stride_tricks.as_strided(source[:,::-1], (10,), (152,))
Out[80]: array([ 19,  38,  57,  76,  95, 114, 133, 152, 171, 190])
英文:
In [40]: target
Out[40]: array([ 18,  37,  56,  75,  94, 113, 132, 151, 170, 189])
In [48]: res = np.diagonal(source[:,::-1],1)[:10]
In [49]: res
Out[49]: array([ 18,  37,  56,  75,  94, 113, 132, 151, 170, 189])

res is view of source, but it's a read-only:

In [54]: source[0,18]=1000
In [55]: res
Out[55]: array([1000,   37,   56,   75,   94,  113,  132,  151,  170,  189])

In [56]: res[0]=18
---------------------------------------------------------------------------
ValueError: assignment destination is read-only

looking at the code for np.diag, we see that it uses arr.flat indexing. So we can get the target directly with:

In [59]: source.flat[18:190:19]
Out[59]: array([1000,   37,   56,   75,   94,  113,  132,  151,  170,  189])

This, though, is not a view.

np.diagonal documents the read-only view bit. Also demonstrates the anti-diagonal. np.diag uses np.diagonal if given a 2d array. arr.diagonal is compiled, but np.diag uses the flat trick to create a diagonal matrix.

In the comment I mentioned using as_strided. This gets 10 anti-diagonal elements, but starting with 19, rather than 18. But for this purpose flat is easier to use.

In [80]: np.lib.stride_tricks.as_strided(source[:,::-1], (10,), (152,))
Out[80]: array([ 19,  38,  57,  76,  95, 114, 133, 152, 171, 190])

答案2

得分: 0

我认为这很困难,因为切片只能按轴执行。你可以使用生成器,这样就不会分配内存。例如像这样:

gen1 = (i for i in np.arange(10))
gen2 = (i for i in 18 - np.arange(10))

target = []
for i, j in zip(gen1, gen2):
    target.append(source[i, j])
英文:

I think it is difficult, because slicing is only performed per axis. What you can do, is to use generators, which has the advantage that no memory will be allocated. For example like this:

gen1 = (i for i in np.arange(10))
gen2 = (i for i in 18 - np.arange(10))

target = []
for i,j in zip(gen1, gen2):
    target.append(source[i,j])

答案3

得分: 0

受 @hpaulj 的回答启发,我认为最节省内存的方法是

np.diagonal(source[:,::-1],1)[:10]

或者

target = np.diagonal(source[:, :18-10:-1], source.shape[1] - 1 - 18)
source.flat[[18, 37]] += 100  # 这将在目标中反映出来
英文:

Inspired by @hpaulj's Answer, I think the most memory efficient ways are

np.diagonal(source[:,::-1],1)[:10]

or

target = np.diagonal(source[:, :18-10:-1], source.shape[1] - 1 - 18)
source.flat[[18, 37]] += 100  # this will be reflected in target

huangapple
  • 本文由 发表于 2023年7月13日 21:01:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76679667.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定