Python 多维数组中向量的numpy第一个非零值
我有一个三维的numpy-ndarray形状(I,j,k),其中每一行是多个大小相似的向量的数组 我想提取一个(I,k)形数组,这样行的每个元素都包含其“j”向量组的第一个非零元素 基本上,给定一个数组,例如:Python 多维数组中向量的numpy第一个非零值,python,arrays,numpy,Python,Arrays,Numpy,我有一个三维的numpy-ndarray形状(I,j,k),其中每一行是多个大小相似的向量的数组 我想提取一个(I,k)形数组,这样行的每个元素都包含其“j”向量组的第一个非零元素 基本上,给定一个数组,例如: [ [ [0 , 10 , 12 , 0 , 4], [0 , 0 , 13 , 1 , 2], [12, 14 , 1 , 12 , 8] ], [ [5 , 17 , 12 , 9 , 0], [0 , 0 , 13
[
[
[0 , 10 , 12 , 0 , 4],
[0 , 0 , 13 , 1 , 2],
[12, 14 , 1 , 12 , 8]
],
[
[5 , 17 , 12 , 9 , 0],
[0 , 0 , 13 , 1 , 0],
[12, 14 , 1 , 12 , 8]
],
[
[0 , 0 , 19 , 0 , 9],
[2 , 6 , 13 , 0 , 2],
[12, 14 , 1 , 12 , 8]
]
]
我希望能找到像这样的东西:
[
[12, 10, 12, 1, 4],
[5 , 17, 12, 9, 8],
[2 , 6, 19, 12, 9]
]
如何有效地找到结果
import numpy as np
i,j,k = 3, 5, 10 #in real problem, these are pretty large
arr = np.random.randint(0, 10000, (i,j,k))
#????????
使用简单的转置和高级索引,解决方案如下所示:
import numpy as np
a = np.array([
[
[0 , 10 , 12 , 0 , 4],
[0 , 0 , 13 , 1 , 2],
[12, 14 , 1 , 12 , 8]
],
[
[5 , 17 , 12 , 9 , 0],
[0 , 0 , 13 , 1 , 0],
[12, 14 , 1 , 12 , 8]
],
[
[0 , 0 , 19 , 0 , 9],
[2 , 6 , 13 , 0 , 2],
[12, 14 , 1 , 12 , 8]
]
])
# swapping the 0 and 1 axes, to make the rest of the code easier
a = a.transpose((1, 0, 2))
# initialising result to zeroes, same shape as a single layer of the transposed a
result = np.zeros(a[0].shape, np.int32)
# one layer at a time
for layer in a:
# as soon as result contains no more zeroes, done
if len(result[result == 0]) == 0:
break
else:
# replace all values of result that are zero
# with values from the same location in layer
result[result == 0] = layer[result == 0]
print(result)
印刷品:
[[12 10 12 1 4]
[ 5 17 12 9 8]
[ 2 6 19 12 9]]
这并不是最优雅的方式,因为我写得相当快。然而,希望这足以让你开始
def find_non_zero(lst):
对于lst中的num:
如果num!=0:
返回数
首先,我们定义了一个非常简单的辅助函数,find_non_zero
,它接收一维列表作为输入,并返回第一个非零条目。然后,当我们在数组
中的二维数组的每列上循环时,将使用此函数,该数组是提供的三维输入数组
将numpy导入为np
数组=[
[
[0 , 10 , 12 , 0 , 4],
[0 , 0 , 13 , 1 , 2],
[12, 14 , 1 , 12 , 8]
],
[
[5 , 17 , 12 , 9 , 0],
[0 , 0 , 13 , 1 , 0],
[12, 14 , 1 , 12 , 8]
],
[
[0 , 0 , 19 , 0 , 9],
[2 , 6 , 13 , 0 , 2],
[12, 14 , 1 , 12 , 8]
]
]
最终结果=[]
对于阵列中的阵列:
array=np.array(array).T
最终结果。追加([为数组中的列查找非零列])
打印(最终结果)
这将产生以下输出
[[12, 10, 12, 1, 4], [5, 17, 12, 9, 8], [2, 6, 19, 12, 9]]
Numpy的.T
transpose操作符很方便,因为它允许我们按列而不是默认行循环二维数组。有关转置运算符的更多信息,请阅读
我很乐意回答您可能有的任何其他问题。使用沿轴应用,然后应用函数nonzero并获取所需轴中的第一个元素
np.apply_along_axis(lambda e: e[np.nonzero(e)][0], 1, x)
或
输出
array([[12, 10, 12, 1, 4],
[ 5, 17, 12, 9, 8],
[ 2, 6, 19, 12, 9]])
根据品味,OP可能更喜欢基于Python的解决方案,而不是只使用
numpy
。正如您所料,它会慢一点-我使用timeit
对您的解决方案和我的numpy
进行了基准测试,我的解决方案大约需要1.41秒进行100000次迭代,而您的解决方案大约需要1.62秒。数字不多,但数组当然很小。
array([[12, 10, 12, 1, 4],
[ 5, 17, 12, 9, 8],
[ 2, 6, 19, 12, 9]])