Python 比较numpy数组中的整行和整列,并删除选定的行和列
我有两个方形数组,其Python 比较numpy数组中的整行和整列,并删除选定的行和列,python,arrays,numpy,tensorflow,Python,Arrays,Numpy,Tensorflow,我有两个方形数组,其shape=(25,25),我想检查整行是否用零填充,以及对应的列是否用零填充。如果是这种情况,我希望从数组中删除这些列和行 例如: array = np.array([[1, 0, 1, 1], [0, 0, 0, 0], [1, 0, 1, 1], [1, 0, 1, 1]]) 我希望它被操纵 array=np.array([[1, 1, 1],
shape=(25,25)
,我想检查整行是否用零填充,以及对应的列是否用零填充。如果是这种情况,我希望从数组中删除这些列和行
例如:
array = np.array([[1, 0, 1, 1],
[0, 0, 0, 0],
[1, 0, 1, 1],
[1, 0, 1, 1]])
我希望它被操纵
array=np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
我希望你能理解我的目的。在本例中,行和列2已被删除,因为它们是零行/列
我可以通过遍历所有这些数组来做到这一点,因为我有1000万个数组,我希望有一个pythonic/高效的方法来解决这个问题
第二个数组是一个tensorflow数组,如果我知道要删除的行和列的索引,这应该不会有问题
编辑:
我现在找到了以下解决方案,但它用于循环:
def removepadding(y_true, y_pred):
shape = np.shape(y_true)
y_true_cleaned=[]
for i in range(shape[0]):
x = y_true[i]
for n in range(shape[1] - 1, -1, -1):
if sum(x[n, :]) == 0 and sum(x[:, n]) == 0:
x = np.delete(np.delete(x, n, 0), n, 1)
y_true_cleaned.append(x)
return y_true_cleaned
编辑:感谢@mad physicator,我们可以使用np.flatnonzero。以下是2d案例:
将numpy导入为np
a=np.数组([[1,0,2,3,0,4],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[2,0,3,4,0,5],
[3,0,4,5,0,6],
[4,0,5,6,0,7],
[5,0,6,7,0,8]])
cols_to_keep=np.flatnonzero(a.sum(axis=0))
行\u至\u keep=np.flatnonzero(a.sum(轴=1))
a=a[:,cols\u to\u keep]
a=a[要保留的行:]
A.
>>>
数组([[1,2,3,4],
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8]])
以下是3d案例:
将numpy导入为np
a=np.array([
[[1,0,2,3,0,4],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[2,0,3,4,0,5],
[3,0,4,5,0,6],
[4,0,5,6,0,7],
[5,0,6,7,0,8]],
[[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0]],
[[5,0,5,5,0,5],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[2,0,3,4,0,5],
[3,0,4,5,0,6],
[4,0,5,6,0,7],
[5,0,6,7,0,8]],
])
ix_保持_轴_0=np.flatnonzero(a.sum(轴=(1,2)))
ix_保持_轴_1=np.flatnonzero(a.sum(轴=(0,2)))
ix_保持_轴_2=np.flatnonzero(a.sum(轴=(0,1)))
a=a[ix_保持_轴0,:,:]
a=a[:,ix_保持_轴_1,:]
a=a[:,:,ix_保持轴2]
A.
>>>
数组([[1,2,3,4],
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8]],
[[5, 5, 5, 5],
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8]]])
您可以在一行中完成:
array[array.any(axis = 1)][:, array.any(axis = 0)]
#array([[1, 1, 1],
# [1, 1, 1],
# [1, 1, 1]])
您可以使用在每个维度的一个步骤中获取索引:
nnz_row = np.count_nonzero(array, axis=1)
nnz_col = np.count_nonzero(array, axis=0)
现在,制作一个掩码,其中两个都为零:
mask = (nnz_row == 0) & (nnz_col == 9)
您可以将遮罩转换为索引并将其传递给:
或者,您可以计算正遮罩:
pmask = nnz_row.astype(bool) | nnz_col.astype(bool)
array = array[pmask, :][:, pmask]
此遮罩可以直接选择,类似于delete
对负片遮罩所做的操作:
pmask = nnz_row.astype(bool) | nnz_col.astype(bool)
array = array[pmask, :][:, pmask]
如果arr中存在负值,
np.sum
可能会失败
对于二维阵列:
import numpy as np
a = np.array([[1,0,2,3,0,4],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[2,0,3,4,0,5],
[3,0,4,5,0,6],
[4,0,5,6,0,7],
[5,0,6,7,0,8]])
row = np.all(a==0, axis=1)
col = np.all(a==0, axis=0)
a[~row][:,~col]
输出
array([[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8]])
对于三维阵列:
a = np.ones((3,3,3))
a[1,:,1] = 0
a[1,1,:] = 0
a[:,1,1] = 0
z = np.all(a==0, axis=2)
y = np.all(a==0, axis=1)
x = np.all(a==0, axis=0)
Z = ~np.array([z]*a.shape[2])
Y = ~np.array([y]*a.shape[1])
X = ~np.array([x]*a.shape[0])
ZZ, YY, XX = (Z*Y*X).nonzero()
a[ZZ, YY, XX]
嘿,谢谢,你的方法看起来不错。我如何有效地扩展您的代码以处理一批这些数组呢?假设我有一个
shape=(512,25,25)
的数组?您可以跳过对where
的调用。在这两种情况下,传入的掩码都可以直接用于索引。如果确实需要索引,请在此处使用np.flatnonzero
。如果希望输出为3D数组,则可能无法将其扩展到3D。一旦你从3D数组中删除一些数据,数组就会崩溃,但你只需要索引,这是非常可行的。感谢你的评论,我编辑了使用np.flatnonzero并展示了一个3D案例。np.any(array!=0,axis=1)
可以简化为array.any(axis=1)
@GZ0漂亮!我简化了它