Python 仅从N维Numpy数组中获取非零子数组
我有一个Python 仅从N维Numpy数组中获取非零子数组,python,arrays,numpy,Python,Arrays,Numpy,我有一个numpy数组'arr',它是形状(1756020,28,28,4)。 基本上,'arr'具有1756020形状(28,28,4)的小数组。在1756020阵列中967210为“全零”,且788810具有所有非零值。我想删除所有967210“全零”小数组。我使用条件arr[I]==0.any()编写了一个if-else循环,但这需要很多时间。有更好的方法吗 将逻辑矢量化的一种方法是与包含未测试维度的轴的元组参数一起使用 # set up 4d array of ones A = np.o
numpy
数组
'arr'
,它是形状(1756020,28,28,4)
。
基本上,
'arr'
具有1756020
形状(28,28,4)的小数组。在1756020
阵列中967210
为“全零”,且788810
具有所有非零值。我想删除所有967210
“全零”小数组。我使用条件arr[I]==0.any()
编写了一个if-else循环,但这需要很多时间。有更好的方法吗 将逻辑矢量化的一种方法是与包含未测试维度的轴的元组参数一起使用
# set up 4d array of ones
A = np.ones((5, 3, 3, 4))
# make second of shape (3, 3, 4) = 0
A[1] = 0 # or A[1, ...] = 0; or A[1, :, :, :] = 0
# find out which are non-zero
res = np.any(A, axis=(1, 2, 3))
print(res)
[True False True True True]
此功能在numpy
v0.17以上版本中提供。根据:
轴:无或整数或整数元组,可选
如果这是整数的元组,则在多个轴上执行缩减,
而不是像以前那样的单个轴或所有轴
我用你提到的大小做了一个小测试脚本。在我的计算机上,数组创建(如果浮动,则内存错误,这就是布尔值的原因)和选择速度很慢,但查找零似乎相当快:
if __name__ == '__main__':
arr = np.ones((1756020, 28, 28, 4), dtype=bool)
for i in range(0,1756020,2):
arr[i] = 0
print(arr[:5])
s = arr.shape
t0 = time.time()
arr2 = arr.reshape((s[0], np.prod(s[1:])))
ok = np.any(arr2, axis=1)
print(time.time()-t0)
arr_clean = arr2[ok]
print(time.time()-t0)
arr_clean = arr_clean.reshape((np.sum(ok), *s[1:]))
print(time.time()-t0)
print('end')
输出:
0.4846000671386719#零的查找速度很快
29.750200271606445#删除零的速度很慢
29.797000408172607#重塑为原始形状[1]很快尝试arr[(arr!=0)。任何(轴=(1,2,3))]
?arr.any(轴(1,2,3))可能更有效,因为第一个非零值足以保持它,不需要计算总数。以下解决方案之一是否有帮助?请随意接受(在左边打勾),或要求澄清。@MateenUlhaq,这正是我所拥有的。区别在于我在识别零数组。不过,这没有根本区别。你相信有吗?我认为arr的问题0表示它创建了一个新的巨大数组。它需要大约5 GB(或其他)内存。也可能A==0是不必要的,为什么不仅仅是res=np呢?任何(A,axis=(1,2,3))?次要的一点:A[1,:,:,:]=0
只相当于A[1]=0
-不需要为后继轴指定切片(显式或使用椭圆)。@AnttiA,对3个选项进行计时(A==0,A!=0,只是A),没有太大的区别。我认为你也不会发现任何记忆上的好处。“你的测试还表明了什么吗?”阿莱克斯利,谢谢-谢谢,我把所有3个都准备好了。