如何编写pythonic代码来修改数组,以便在对其行执行操作时将其关闭

2024-05-16 01:35:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数组A[:,:],和一个作用于A的x=A[:,J]行的操作Op。 因此,对于A的每一行x,我获得Op(x)。如果Op(x)不是a的一行,我将它附加到a。我这样做直到a在Op下闭合(我假设Op不会产生无延续循环,即Op在一定次数的迭代下闭合)。在这个过程的最后,给出了扩展的A在Op下闭合,我还需要置换Pindex,使得Op(A[:,J])=A[:,Pindex(J)]

我已经能够编写Python代码来实现这一点:

import numpy as np

A=np.array([[0,2,3],
            [0,-3,-1],
            [0,4,3]])

def Op(x):
    return [0,-x[2],x[1]-x[2]]



A=A.tolist()

last=len(A)
Pindex=[]

for i,x in enumerate(A):
    found=False 
    xOp=Op(x)
    for j,y in enumerate(A):
        if np.array_equal(y,xOp):
            Pindex.append(j)
            found=True
            break
    if not found:
        A.append(xOp)
        Pindex.append(last)
        last+=1

A=np.asarray(A)      


print A      
print Pindex
print A[Pindex]

然而,在我看来,它并不是很“pythonic”。我想它可以改进,使它更快。有什么建议吗

另外,这是更大代码的一部分,我需要使用数组。我需要将数组转换为列表,因为我需要更新迭代对象的长度。也许有一种更聪明的方法可以只使用阵列来实现这一点

p.p.S。 我不确定问题的标题。如果你有建议,我可以改一下


Tags: 代码inforifnp数组arraylast
1条回答
网友
1楼 · 发布于 2024-05-16 01:35:59

如果对op进行向量化(python约定使用snake_case),那么当然可以对循环的内容进行向量化。例如,给定起始数组

A = np.array([[0, 2, 3],
              [0,-3,-1],
              [0, 4, 3]])

首先定义可以同时处理整个事情的op

def op(x):
    return np.stack((x[:, 0], -x[:, 2], x[:, 1] - x[:, 2]), axis=1)

您可以通过首先屏蔽A中已经重复的部分来组合数组。使用@Untubu's ^{} approach^{}组合

dt = np.dtype((np.void, A.dtype.itemsize * A.shape[-1]))

def asvoid(arr):
    arr = np.ascontiguousarray(arr)
    if np.issubdtype(arr.dtype, np.floating):
        arr += 0.
    return arr.view(dt).squeeze()

要构建阵列,您的循环可以是:

while True:
    B = op(A)
    mask = np.in1d(asvoid(B), asvoid(A), invert=True)
    if mask.any():
        A = np.concatenate((A, B[mask]), axis=0)
    else:
        break

完成后,将有两个行排列:Aop(A)。您可以使用类似于https://stackoverflow.com/a/42232761/2988730中的技术从一个到另一个计算排序索引:

oa = np.argsort(asvoid(A), axis=0)
ob = np.argsort(asvoid(B), axis=0)
ib = np.empty_like(oa)
ib[ob] = np.arange(B.shape[0])
J = oa[ib]

您还可以增量地构建J,因为您知道给定迭代中A的每个元素已经有一个J,而上一次迭代(B)的增量可能有,也可能没有。事实上,如果保证了闭包,则只需对不断缩小的B调用op。唯一的问题是,在添加B元素以便于搜索时,必须按排序顺序维护A(argsorted很好)

相关问题 更多 >