有效地查找具有特定条件的numpy数组中的行
Finding rows in numpy array with specific condition efficiently
我有两个 numpy 二维数组。我想要做的是在 np_sentence
.
中找到 np_weight
的特定行
例如:
#rows are features, columns are clusters or whatever
np_weight = np.random.uniform(1.0,10.0,size=(7,4))
print(np_weight)
[[9.96859395 8.65543961 6.07429382 4.58735497]
[3.21776471 8.33560037 2.11424961 8.89739975]
[9.74560314 5.94640798 6.10318198 7.33056421]
[6.60986206 2.36877835 3.06143215 7.82384351]
[9.49702267 9.98664568 3.89140374 5.42108704]
[1.93551346 8.45768507 8.60233715 8.09610975]
[5.21892795 4.18786508 5.82665674 8.28397111]]
#rows are sentence index, columns are words on that sentence
np_sentence = np.random.randint(0.0,7.0,size=(5,3))
print(np_sentence)
[[2 5 1]
[1 6 4]
[0 0 0]
[2 3 6]
[4 2 4]]
如果我对每一列进行 np_weight
排序,然后获得前 5 名,我将拥有这一列
(这里只显示第一列):
temp_sorted_result=
[9.96859395 ] --->index=0
[9.74560314 ] --→ index=2
[9.49702267 ] --→ index=4
[6.60986206 ] --->index=3
[5.21892795 ] --->index=6
现在,我想在第二个 numpy 数组 np_sentence
中逐个搜索这些索引,看看是否有任何包含两个索引的行。
例如,基于此它必须输出:1,3,4
。这些是 np_sentence
的索引,其中包括 temp_sorted_result
.
中两个索引的组合
例如temp_sorted_result
中可用的both 4 and 6
与row=1
中的np_sentence
在同一行,依此类推。
我需要为 np_weight
的每一列执行此操作。拥有一个非常高效的代码对我来说非常重要,因为行数非常大
到目前为止我所做的只是在第二个数组中搜索一个项目,这不是我最终想要的:
一种方法是我为每一列形成所有组合,例如对于上面显示的第一列 temp_sorted_result
,我形成
(0,2) (0,4)(0,3) (0,6)
(2,4) (2,3) (2,6)
(4,3)(4,6)
(3,6)
然后检查np_sentence
行中有哪一个可用。基于我的 np_sentence
行索引 1,3,4
包含其中一些。
现在我的问题是,我怎样才能以最有效的方式实现它?
如果不明显请告诉我。
感谢您的帮助:)
这是一种方法:下面的函数 f
创建一个与 weight
形状相同的掩码(加上一个 False
s 的虚拟行)标记每个中的前五个条目True
.
列
然后它使用 np_sentence
索引到掩码中并计算每个列、行对的 True
并与阈值二进行比较。
唯一的困难:我们必须抑制 np_sentence
行中的重复值。为此,我们对行进行排序,然后将等于其左邻居的每个索引指向掩码中的虚拟行。
这个函数returns一个掩码。脚本的最后一行演示了如何将该掩码转换为索引。
import numpy as np
def f(a1, a2, n_top, n_hit):
N,M = a1.shape
mask = np.zeros((N+1,M), dtype=bool)
np.greater_equal(
a1,a1[a1.argpartition(N-n_top, axis=0)[N-n_top], np.arange(M)],
out=mask[:N])
a2 = np.sort(a2, axis=1)
a2[:,1:][a2[:,1:]==a2[:,:-1]] = N
return np.count_nonzero(mask[a2], axis=1) >= n_hit
a1 = np.matrix("""[[9.96859395 8.65543961 6.07429382 4.58735497]
[3.21776471 8.33560037 2.11424961 8.89739975]
[9.74560314 5.94640798 6.10318198 7.33056421]
[6.60986206 2.36877835 3.06143215 7.82384351]
[9.49702267 9.98664568 3.89140374 5.42108704]
[1.93551346 8.45768507 8.60233715 8.09610975]
[5.21892795 4.18786508 5.82665674 8.28397111]]"""[2:-2].replace("]\n [",";")).A
a2 = np.matrix("""[[2 5 1]
[1 6 4]
[0 0 0]
[2 3 6]
[4 2 4]]"""[2:-2].replace("]\n [",";")).A
print(f(a1,a2,5,2))
from itertools import groupby
from operator import itemgetter
print([[*map(itemgetter(1),grp)] for k,grp in groupby(np.argwhere(f(a1,a2,5,2).T),itemgetter(0))])
输出:
[[False True True True]
[ True True True True]
[False False False False]
[ True False True True]
[ True True True False]]
[[1, 3, 4], [0, 1, 4], [0, 1, 3, 4], [0, 1, 3]]
我有两个 numpy 二维数组。我想要做的是在 np_sentence
.
np_weight
的特定行
例如:
#rows are features, columns are clusters or whatever
np_weight = np.random.uniform(1.0,10.0,size=(7,4))
print(np_weight)
[[9.96859395 8.65543961 6.07429382 4.58735497]
[3.21776471 8.33560037 2.11424961 8.89739975]
[9.74560314 5.94640798 6.10318198 7.33056421]
[6.60986206 2.36877835 3.06143215 7.82384351]
[9.49702267 9.98664568 3.89140374 5.42108704]
[1.93551346 8.45768507 8.60233715 8.09610975]
[5.21892795 4.18786508 5.82665674 8.28397111]]
#rows are sentence index, columns are words on that sentence
np_sentence = np.random.randint(0.0,7.0,size=(5,3))
print(np_sentence)
[[2 5 1]
[1 6 4]
[0 0 0]
[2 3 6]
[4 2 4]]
如果我对每一列进行 np_weight
排序,然后获得前 5 名,我将拥有这一列
(这里只显示第一列):
temp_sorted_result=
[9.96859395 ] --->index=0
[9.74560314 ] --→ index=2
[9.49702267 ] --→ index=4
[6.60986206 ] --->index=3
[5.21892795 ] --->index=6
现在,我想在第二个 numpy 数组 np_sentence
中逐个搜索这些索引,看看是否有任何包含两个索引的行。
例如,基于此它必须输出:1,3,4
。这些是 np_sentence
的索引,其中包括 temp_sorted_result
.
例如temp_sorted_result
中可用的both 4 and 6
与row=1
中的np_sentence
在同一行,依此类推。
我需要为 np_weight
的每一列执行此操作。拥有一个非常高效的代码对我来说非常重要,因为行数非常大
到目前为止我所做的只是在第二个数组中搜索一个项目,这不是我最终想要的:
一种方法是我为每一列形成所有组合,例如对于上面显示的第一列 temp_sorted_result
,我形成
(0,2) (0,4)(0,3) (0,6)
(2,4) (2,3) (2,6)
(4,3)(4,6)
(3,6)
然后检查np_sentence
行中有哪一个可用。基于我的 np_sentence
行索引 1,3,4
包含其中一些。
现在我的问题是,我怎样才能以最有效的方式实现它?
如果不明显请告诉我。
感谢您的帮助:)
这是一种方法:下面的函数 f
创建一个与 weight
形状相同的掩码(加上一个 False
s 的虚拟行)标记每个中的前五个条目True
.
然后它使用 np_sentence
索引到掩码中并计算每个列、行对的 True
并与阈值二进行比较。
唯一的困难:我们必须抑制 np_sentence
行中的重复值。为此,我们对行进行排序,然后将等于其左邻居的每个索引指向掩码中的虚拟行。
这个函数returns一个掩码。脚本的最后一行演示了如何将该掩码转换为索引。
import numpy as np
def f(a1, a2, n_top, n_hit):
N,M = a1.shape
mask = np.zeros((N+1,M), dtype=bool)
np.greater_equal(
a1,a1[a1.argpartition(N-n_top, axis=0)[N-n_top], np.arange(M)],
out=mask[:N])
a2 = np.sort(a2, axis=1)
a2[:,1:][a2[:,1:]==a2[:,:-1]] = N
return np.count_nonzero(mask[a2], axis=1) >= n_hit
a1 = np.matrix("""[[9.96859395 8.65543961 6.07429382 4.58735497]
[3.21776471 8.33560037 2.11424961 8.89739975]
[9.74560314 5.94640798 6.10318198 7.33056421]
[6.60986206 2.36877835 3.06143215 7.82384351]
[9.49702267 9.98664568 3.89140374 5.42108704]
[1.93551346 8.45768507 8.60233715 8.09610975]
[5.21892795 4.18786508 5.82665674 8.28397111]]"""[2:-2].replace("]\n [",";")).A
a2 = np.matrix("""[[2 5 1]
[1 6 4]
[0 0 0]
[2 3 6]
[4 2 4]]"""[2:-2].replace("]\n [",";")).A
print(f(a1,a2,5,2))
from itertools import groupby
from operator import itemgetter
print([[*map(itemgetter(1),grp)] for k,grp in groupby(np.argwhere(f(a1,a2,5,2).T),itemgetter(0))])
输出:
[[False True True True]
[ True True True True]
[False False False False]
[ True False True True]
[ True True True False]]
[[1, 3, 4], [0, 1, 4], [0, 1, 3, 4], [0, 1, 3]]