我正在尝试使用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。
感谢任何帮助,建议,评论。
答案 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_tol
和max_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)
虽然我现阶段真的不确定......