Numpy in1D多个评估报表

时间:2016-09-13 12:19:10

标签: python numpy evaluation

我正在尝试使用numpy而不是嵌套for循环并尝试查找某个值是否在特定容差范围内。

使用嵌套循环的python中的代码工作正常,我确实得到了我正在寻找的结果,但遗憾的是不可扩展,并且当列表的大小为200k加上项目时需要几个小时。

我现在作为该过程的第二次迭代是:

import numpy as np
import numpy.ma as ma
from numpy import newaxis

#some data provided as an example
a= np.array([['id1', 8988, 7997, 210.0, 240.0, 180, 300, 7000.0, 9038, 8938, 8047, 7947, 231.0, 189.0, 8400.0, 5600.0],
['id2', 7314, 5613, 210.0, 240.0, 180, 300, 7000.0, 7364, 7264, 5663, 5563, 231.0, 189.0, 8400.0, 5600.0],
['id3', 5520, 9888, 35.0, 55.0, -125, 235, 7000.0, 5570, 5470, 9938, 9838, 38.5, 31.5, 8400.0, 5600.0],
['id4', 6270, 4270, 0.0, 90.0, -90, 270, 7000.0, 6320, 6220, 4320, 4220, 0.0, 0.0, 8400.0, 5600.0]])

print(a)

validation = np.ma.MaskedArray(((a[:, 1:2] <= a[:, 8:9]) & (a[:, 1:2] >= a[:, 9:10])) \
    & ((a[:, 2:3] <= a[:, 10:11]) & (a[:, 2:3] >= a[:, 11:12])) \
    & ((a[:, 3:4] <= a[:, 12:13]) & (a[:, 3:4] >= a[:, 13:14])) \
    & ((a[:, 7:8] <= a[:, 14:15]) & (a[:, 7:8] >= a[:, 15:])))

e = np.in1d(a[:, 1:2], a[validation]) <-- this is were I try to apply the check for tolerances
e1 = np.where(e[:, newaxis], a[:, :1], np.zeros(1, dtype=int))
ef = e1[~np.all(e1 == 0, axis=0)]

print('Final array', ef)

第一次尝试使用numpy的meshgrid创建所有组合,每次比较一次,然后对结果进行numpy.where工作但是当使用100k加上项目时,所需的RAM总量超过150GB RAM。

感谢任何帮助,建议,评论。

2 个答案:

答案 0 :(得分:0)

如果我复制粘贴你的a我得到一个4x16字符串数组

In [37]: a
Out[37]: 
array([['id1', '8988', '7997', '210.0', '240.0', '180', '300', '7000.0',
        '9038', '8938', '8047', '7947', '231.0', '189.0', '8400.0',
        '5600.0'],
      ....
      dtype='<U6')

validation表达式应用于该表达式(忘记Maskedarray位)。当然,它试图对字符串进行比较。

array([[ True],
       [ True],
       [ True],
       [ True]], dtype=bool)

如果我删除id列,我会获得4x15的浮动

In [39]: a
Out[39]: 
array([[ 8988. ,  7997. ,   210. ,   240. ,   180. ,   300. ,  7000. ,
         9038. ,  8938. ,  8047. ,  7947. ,   231. ,   189. ,  8400. ,
         5600. ],
...]])

我认为validation测试可以简化为:

In [41]: ((a[:, 0] <= a[:, 7]) & (a[:, 0] >= a[:, 8])) \
    ...:     & ((a[:, 1] <= a[:, 9]) & (a[:, 1] >= a[:, 10])) \
    ...:     & ((a[:, 2] <= a[:, 11]) & (a[:, 2] >= a[:, 12])) \
    ...:     & ((a[:, 6] <= a[:, 13]) & (a[:, 6] >= a[:, 14]))
Out[41]: array([ True,  True,  True,  True], dtype=bool)

这是做什么的?

e = np.in1d(a[:, 1:2], a[validation])

a[validation]ok的所有a行; a[:,0]是每行的第一个值。但是np.in1d是为了检查一个1d数组的内容与另一个1d的内容。正如你所写,它使用的是2个2d数组。

此时,我要放弃了。

构建一个更简单的测试用例,并确保它在每一步都有效。显示中间值。然后我们可以讨论它不起作用的步骤。

答案 1 :(得分:0)

正如hpaulj所说,首先摆脱id的。

其次,为什么你的公差和你的价值在同一个数组?如果您在单独的数组中有min_tolmax_tol,则可以更轻松地执行此操作。

您可能需要(删除id之后):

min_tol = a[:, 8:15:2]
max_tol = a[:, 7:14:2]
a_val = np.c_[a[:, :3], a[:, 6]]
validation = (a_val >= min_tol) & (a_val <= max_tol)

虽然我现阶段真的不确定......