删除4D数组中存在的3D数组行

2024-09-28 21:49:46 发布

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

我有一个三维数组=a包含空间中点的坐标。 通过矩阵运算对这个数组进行变换,得到了4D numpy数组,这样在矩阵变换(包括恒等运算)后,a的每一行在4D数组中都有一个对应的3D块。所以两个数组的零轴相等。在

现在,我需要找出索引为[I]的任何行是否存在于第j行(如果存在),然后移除I或j(不管它是I还是j)。还有我=!j因为我们有身份认证。举例说明:

>>> a  # 3d array
array([[[0, 1, 2],
        [0, 0, 2]],

       [[2, 0, 0],
        [0, 0, 2]],

       [[0, 2, 1],
        [0, 0, 0]]])

>>> b  #4d array after applying transformation to 3d array(a)
array([[[[0, 1, 2],
         [0, 0, 2]],

        [[0, 0, 0],
         [2, 1, 1]],

        [[0, 2, 1],
         [0, 0, 1]]],


       [[[2, 0, 0],
         [0, 0, 2]],

        [[0, 2, 2],
         [2, 0, 0]],

        [[2, 2, 2],
         [1, 0, 2]]],


       [[[0, 2, 1],
         [0, 0, 0]],

        [[2, 0, 0],
         [0, 0, 2]],

        [[2, 0, 1],
         [2, 2, 0]]]])

现在,如果你仔细看,a和b是一样的[:,0]。原因是身份转变。所以我们当然不想将a[0]与b[0]进行比较。 a[1]=b[2,0],因此代码应该删除a[1]或a[2],但不能同时删除这两者。 最终结果应为:

^{pr2}$

或者

>>> output
array([[[0, 1, 2],
        [0, 0, 2]],

       [[0, 2, 1],
        [0, 0, 0]]])

第一个sol. 索尔。到目前为止我只有这个

def giveuniquestructures_fast(marray, symarray, noofF):
    """ Removes configurations ith (2d block of marray) which are found in symmarray at jth position such that i != j """

# noofF is the number of points in each configuration(i.e. noofF = len(marray[0])
# The shape of the two arrays is, marray 3D-array(positions, nofF, 3),
# symarray 4D-array(positions, symmetryopration, noofF, 3)


print("Sorting the input arrays:\\n")

symarray = sort4D(symarray)    # sorting the symarray(4D-array)

marray = sorter3d_v1(marray)    # sorting the marray(3D-array)
print("sorting is complete now comparison is starting: ")

delindex = np.empty(0, dtype=int) 
delcheck = False
print("The total number of configurations are", len(marray))

 # flattening the array to reduce one dimension

symarray = symarray.reshape(marray.shape[0],-1,3*noofF) 
marray = marray.reshape(-1, 3*noofF)
bol = np.ones(symarray.shape[0], dtype=bool)
     # boolean array for masking the symarray along 0-axis

for i in range(len(marray)):

        print("checking %dth configuration for symmetrical equivalencey \\n" % i)
        bol[i] = False
        bol1 = marray[i] == symarray[bol]
        bol1 = bol1.all(-1)
        bol[i] = True # setting it back to true for next run

        if bol1.any() :

            delindex = np.append(delindex, i)
            delcheck = True

if delcheck:

    marray = np.delete(marray, delindex, 0)

print("Search for UNique configurations are ending now :\\n")
return marray.reshape(-1, noofF,3)  # converting back to input shape

----------以防万一你想看到排序功能----------------

def sorter3d_v1(a):

    """sorts the 1D blocks within 2D blocks of array in order of first column, 2nd column, 3rd column"""

    print("Input array is \\n", a)
    print("shape of input array is ",a.shape)
    ind = np.lexsort((a[:,:,2], a[:,:,1], a[:,:,0]), axis=1)  # getting the sorter index

    s = np.arange(len(a))[:,np.newaxis] # getting the evenly distributed number array  based on length of ind to select the sorted

    a = a[s,ind,:]

    print("sorted array is \\n")
    print(a)

    return  a

正如您可能已经猜到的,这个函数的问题是效率。如果输入数组的行数甚至是百万分之一,那么循环运行将花费大量时间。瓶颈实际上在于使用的语句np.全部()功能,即

bol1 = bol1.all(-1)

如有任何帮助,我们将不胜感激。我希望这不会让人困惑。在

第二个解决方案 第二个解决方案,我能够用矢量化进行编码:

def giveuniquestructures_fast_v1(marray, symarray, noofF):
    """The new implementation of the previous function (uniquestructures_fast) """

    # The shape of the two arrays is, marray 3D-array(positions, nofF, 3),
    # symarray 4D-array(positions, symmetryopration, noofF, 3)

    try:

        if (len(marray) != len(symarray)):
            raise Exception("The length of the two arrays doesn't match")

    except Exception:
        raise

    print("Sorting the input arrays:\\n")

    symarray = sort4D(symarray)  # sorting the barray(4D-array)

    marray = sorter3d_v1(marray)  # sorting the marray(3D-array)
    print("sorting is complete now comparison is starting: ")
    print("The total number of configurations is", len(marray))

    # flattening the array to reduce one dimension

    symarray = symarray.reshape(symarray.shape[0], -1, 3 * noofF)
    marray = marray.reshape(-1, 3 * noofF)

    # Batch operation may give Memory error in case array is big!!! 

    bol = marray[:,np.newaxis,np.newaxis,:] == symarray  # 4d array
    maskindices = np.arange(len(bol)) # to falsify the identity matrix operaterated values
    bol[maskindices[:,np.newaxis], maskindices[:,np.newaxis]] = False  # setting the identity rows value to False
    delindices   = np.where(bol.all(-1)) # The first and second tuple entries are relevant for next step

    # Need to check for swapping indices as possibility of removing both equal arrays may happen

    # removing the configurations which are symmetrically equivalent
    marray = np.delete(marray, np.unique(delindices,axis=-1)[0], 0)

    # reverting the dimensions back to the input array dimensions

    marray = marray.reshape(-1, noofF, 3)
    print("Search for UNique configurations are ending now :\\n")
    return marray

第二个电磁阀有问题。 当数组变得足够大而引发内存错误时,矢量化没有帮助。有什么想法吗?!!在


Tags: ofthetoforlenisnp数组