import numpy as np
cimport numpy as np
x = np.array(
[[1,1,0.293729457],
[1,2,0.414213648],
[1,3,0.420339974],
[2,1,0.394448377],
[2,2,0.550755237],
[2,3,0.876993966]
]
)
我有一个6x3矩阵。第1列和第2列是索引,第3列是值。 问题是如何快速查找第1列和第2列的值?例如,如果col 1 = 1且col 2 = 3,我想要返回0.420339974。
我尝试循环查找每列,但如果我有很多行,它会很慢。
答案 0 :(得分:1)
杰森,
您可以按如下方式使用np.where
和np.logical_and
,如下所示:
In [10]: x[np.where(np.logical_and(x[:,0]==1,x[:,1]==3))][0][2]
Out[10]: 0.42033997400000001
稍微解释一下,x[:,0]==1
和x[:,1]==3
返回布尔数组,大小等于x
的长度。首先,让我们定义两个变量来存储您的条件:
In [12]: a = x[:,0]==1
In [13]: b = x[:,1]==3
你不能使用Python的内置and
,因为它会首先尝试将其参数转换为布尔值:
a and b
相反,使用numpy的In [15]: a and b
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-15-cb10dcaa1a1e> in <module>()
----> 1 a and b
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
返回一个元素方式的数组。然后,numpy logical_and
函数返回其参数为true的索引。从技术上讲,where
的输出是一个元组,其第一个元素是一个索引数组,其中where
的计算结果为真:
logical_and
使用单个数组作为参数调用的 In [16]: np.logical_and(a,b)
Out[16]: array([False, False, True, False, False, False], dtype=bool)
In [17]: np.where(np.logical_and(a,b))
Out[17]: (array([2]),)
等同于numpy的where
:
nonzero
最后,看起来您的数据可以更逻辑地组织(并且更紧凑,就此而言)仅作为值的二维矩阵:
In [18]: np.nonzero(np.logical_and(a,b))
Out[18]: (array([2]),)
然后你的查找是微不足道的,尽管从基于1的索引切换到基于0的索引:
In [25]: M = 2
In [26]: N = 3
In [27]: data = np.zeros((M,N))
In [28]: for datum in x:
data[datum[0]-1,datum[1]-1]=datum[2]
In [30]: data
Out[30]:
array([[ 0.29372946, 0.41421365, 0.42033997],
[ 0.39444838, 0.55075524, 0.87699397]])
-Ravi
答案 1 :(得分:1)
在我深入了解libcpp之后,我使用了以下
from libcpp.map cimport map
import numpy as np
cimport numpy as np
x = np.array(
[[1,1,0.293729457],
[1,2,0.414213648],
[1,3,0.420339974],
[2,1,0.394448377],
[2,2,0.550755237],
[2,3,0.876993966]
]
)
def F(int c1, int c2, x = x):
cdef map[int, map[int, float]] my_map
cdef int i
for i in xrange(x.shape[0]):
my_map[x[i,0]][x[i,1]] = x[i,2]
return my_map[c1][c2]
print F(1,2)
它的工作方式类似于你的2d矩阵查找。
答案 2 :(得分:0)
这实际上取决于您的用例以及数据集的大小。如果您只需要查询一次数据集,我担心,您最终无法避免遍历所有行。
但是,如果您可以承担一些计算开销来预处理数据集以快速执行多个后续查询,那么我们会想到几种方法。
i, j
)直接对应于具有这些索引的原始数组中的行。如果您的原始数据已经排序且是同质的,那么甚至可以使用简单的ndarray.reshape
来完成。 有许多事情可以尝试。首先,你需要决定要使用的算法,然后才能看看Cython是否值得用来优化它。