【问题标题】:efficient way to extract non None arrays from numpy ndarray从 numpy ndarray 中提取非 None 数组的有效方法
【发布时间】:2021-12-09 20:02:09
【问题描述】:

如果这个问题看起来很长而且很基本,请提前致以诚挚的歉意。

鉴于:

import numpy as np
import time

c, q = int(3e5), int(5e5)    
a = np.full( (c,q,3), None )

# fillout with some non None arrays: 3D (x,y,z) positions
a[0,0, :] = np.array([-4,0.1,0])
a[0,1, :] = np.array([9.2,3.1,0])
a[0,5, :] = np.array([3,-4.3,0])
a[0,6, :] = np.array([-1,12.8,0])

a[2,1, :] = np.array([4.5,-9,0])
a[2,3, :] = np.array([-0.1,6.1,0])
a[2,8, :] = np.array([-7,1,0])

a[3,0, :] = np.array([-1,0.7,0])
a[3,6, :] = np.array([-15,26,0])

a[5,0, :] = np.array([0.1,-1.1,0])

a[7,5, :] = np.array([0,0,0])

a[8,2, :] = np.array([5,6,0])

a[9,10, :] = np.array([-1.1,1,0])

a[10,3, :] = np.array([-32,15,0])

a[11,7, :] = np.array([0,9.3,0])

a[12,2, :] = np.array([0.9,6.2,0])

a[14,9, :] = np.array([8.6,5.6,0])

a[15,5, :] = np.array([0.5,8.5,0])

目标:

我想从a 中提取非None 元素。目前,由于我使用的是基本的for loop,因此我的以下代码非常耗时且效率很低:

bt = time.time()
for ci in range(c):
    if any(ci == value for value in [2, 5]):
        print(f">> Generating {ci}+ ranks ...")
        poseNplus = []
        aNplus = a[ci:]
        for ci_i in range(aNplus.shape[0]):
            aNplus_Q = aNplus[ci_i]
            for qi in range(aNplus_Q.shape[0]):
                if all(aNplus_Q[qi] != None):
                    poseNplus.append( aNplus_Q[qi] )
        print(len(poseNplus), poseNplus)
et = time.time()
print(f"Took {(et-bt):.3f} s")

这很花时间:

Took 580.888 s

按照@Marc Felix 的回答,我可以按如下方式提取非None 三元组的ALL:首先更改a = np.full( (c,q,3), np.nan ),然后:

bt = time.time()
nan_values = np.any(np.isnan(a), axis=-1)
result = a[nan_values==False].reshape((-1, 3))
et = time.time()
print(f"Took {(et-bt):.3f} s")
print(result.shape)
print(result)

返回:

Took 0.318 s
(18, 3)
[[ -4.    0.1   0. ]
 [  9.2   3.1   0. ]
 [  3.   -4.3   0. ]
 [ -1.   12.8   0. ]
 [  4.5  -9.    0. ] <<<--- rank2 - END: from here till end
 [ -0.1   6.1   0. ]
 [ -7.    1.    0. ]
 [ -1.    0.7   0. ]
 [-15.   26.    0. ]
 [  0.1  -1.1   0. ] <<<--- rank5 - END: from here till end
 [  0.    0.    0. ]
 [  5.    6.    0. ]
 [ -1.1   1.    0. ]
 [-32.   15.    0. ]
 [  0.    9.3   0. ]
 [  0.9   6.2   0. ]
 [  8.6   5.6   0. ]
 [  0.5   8.5   0. ]]

但我想要的结果应该是这样的:

>> Generating 2+ ranks ...
[[  4.5  -9.    0. ]
 [ -0.1   6.1   0. ]
 [ -7.    1.    0. ]
 [ -1.    0.7   0. ]
 [-15.   26.    0. ]
 [  0.1  -1.1   0. ]
 [  0.    0.    0. ]
 [  5.    6.    0. ]
 [ -1.1   1.    0. ]
 [-32.   15.    0. ]
 [  0.    9.3   0. ]
 [  0.9   6.2   0. ]
 [  8.6   5.6   0. ]
 [  0.5   8.5   0. ]]
------------------------------------------------------------
>> Generating 5+ ranks ...
[[  0.1  -1.1   0. ]
 [  0.    0.    0. ]
 [  5.    6.    0. ]
 [ -1.1   1.    0. ]
 [-32.   15.    0. ]
 [  0.    9.3   0. ]
 [  0.9   6.2   0. ]
 [  8.6   5.6   0. ]
 [  0.5   8.5   0. ]]
------------------------------------------------------------

问题:

还有其他省时的方法吗?

我知道this 的帖子,但它导致:

b = a[a != None]
print(b)

[-4.0 0.1 0.0 9.2 3.1 0.0 3.0 -4.3 0.0 -1.0 12.8 0.0 4.5 -9.0 0.0 -0.1 6.1
 0.0 -7 1 0 -1.0 0.7 0.0 -15 26 0 0.1 -1.1 0.0 0 0 0 5 6 0 -1.1 1.0 0.0
 -32 15 0 0.0 9.3 0.0 0.9 6.2 0.0 8.6 5.6 0.0 0.5 8.5 0.0]

【问题讨论】:

  • 所以你想提取所有至少有一个元素不同于None的三元组?
  • 没错!但我的方法效率低下!
  • 排名怎么样?这是什么意思?
  • 这 np.array([9.2,3.1,0]) 也应该在输出中吗?
  • 其实没有!它应该返回从np.array([4.5,-9,0]) 开始的所有 3D 姿势(2+ 等级)和np.array([0.1,-1.1,0]) 5+ 等级!

标签: python numpy numpy-ndarray nonetype


【解决方案1】:

修改@Marc Felix 答案和a 修改使用np.full 作为提问者的更新:

nan_values = np.any(np.isnan(a[2:]), axis=-1)
result = a[2:][nan_values==False].reshape((-1, 3))
print(f">> Generating {2}+ ranks ...\n", result, '\n ------------------------------------------------------------')

nan_values = np.any(np.isnan(a[5:]), axis=-1)
result = a[5:][nan_values==False].reshape((-1, 3))
print(f">> Generating {5}+ ranks ...\n", result, '\n ------------------------------------------------------------')

会得到预期的结果。

【讨论】:

    【解决方案2】:

    您可以使用 np.isnan() 检测 nan 值。如下所示:

    nan_values = np.any(np.isnan(a), axis=-1)
    

    那么以下应该会给你正确的结果:

    result = a[nan_values==False].reshape((-1, 3))
    

    【讨论】:

    • 我的回答有一点小错误,我用了一个 np.any() 太多了。现在应该是正确的。
    • 它会被TypeError: ufunc 'isnan' not supported for the input types卡住!?
    • 它返回错误:TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe' 由于dtype=object 我相信
    • 我根据您的回答更新了我的问题,它仍然没有返回我正在寻找的内容,但时机要好得多。我很感激
    猜你喜欢
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2014-01-02
    • 1970-01-01
    • 2014-10-23
    • 2017-12-07
    • 1970-01-01
    相关资源
    最近更新 更多