我试图将2d数组的值与列表进行匹配,以便创建一个新的2d数组,其中包含列表及其对应的2d数组值。代码可能比英语更容易理解......
import numpy as np
m_out = np.arange(50).reshape(25,2)
m_out_list = list(m_out[:,1])
eqn_out = range(7,17)
c_list = [(x,y) for x in eqn_out for y in m_out[:,0] if x in (m_out_list)]
print c_list
此代码产生了我期望的答案,
[(7, 0), (7, 2), (7, 4), (7, 6), ...
然而,这不是我想要完成的事情。我希望列表理解的最后一部分(或任何其他有效的方法)是提供一个匹配eqn_out列表的数组及其对应的唯一原始值;即
[(7,6), (9,8), (11,10), (13,12), (15,14), (17,16)]
我不确定如何准确地做到这一点,任何建议都会非常感激。
答案 0 :(得分:3)
类似的东西:
[(j, i) for (i,j) in m_out if j in eqn_out]
似乎有效。但是,它可能有点浪费,因为我们在整个m_out
而不是子集上进行迭代。
另一种选择可能是:
test = reduce(np.logical_or,v(m_out[:,1]==i for i in eqn_out))
[(j,i) for (i,j) in m_out[test]]
在这里,我们迭代len(eqn_out)
个布尔数组,我们将它们与reduce(np.logical_or, ...)
组合在一起。我们使用这个布尔数组从m_out
中选择我们想要的项目。因为您希望第一列的元素首先出现,所以我们必须使用最后一个列表理解。
请注意,它需要创建至少2个N个布尔数组,这可能比第一个解决方案更浪费......但是,这两个解决方案可以轻松应用于比2更多的列。
答案 1 :(得分:3)
[编辑首先采用更简单的方法。]
在实践中,我可能只是这样做:
In [166]: d = dict(m_out[:,::-1])
In [167]: [(k, d[k]) for k in eqn_out if k in d]
Out[167]: [(7, 6), (9, 8), (11, 10), (13, 12), (15, 14), (17, 16)]
但是为了好玩,坚持不懈,怎么样:
[更新:更好的numpy方法]:
In [15]: m_out[np.in1d(v, eqn_out)][:, ::-1]
Out[15]:
array([[ 7, 6],
[ 9, 8],
[11, 10],
[13, 12],
[15, 14],
[17, 16]])
或者我最初的numpy方法:
In [150]: import numpy as np
In [151]: m_out = np.arange(50).reshape(25,2)
In [152]: v = m_out[:,1]
In [153]: eqn_out = np.arange(7, 18)
In [154]: eqn_out
Out[154]: array([ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
只保留我们了解的值:
In [155]: np.intersect1d(eqn_out, v)
Out[155]: array([ 7, 9, 11, 13, 15, 17])
找到他们所在的位置(假设数据已排序!!):
In [156]: v.searchsorted(np.intersect1d(eqn_out, v))
Out[156]: array([3, 4, 5, 6, 7, 8])
将这些指数用于选择目的:
In [157]: m_out[v.searchsorted(np.intersect1d(eqn_out, v))]
Out[157]:
array([[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15],
[16, 17]])
翻转:
In [158]: m_out[v.searchsorted(np.intersect1d(eqn_out, v))][:,::-1]
Out[158]:
array([[ 7, 6],
[ 9, 8],
[11, 10],
[13, 12],
[15, 14],
[17, 16]])