我有一个值数组以及另一个要为其创建索引的数组。 例如:
value_list = np.array([[2,2,3],[255,243,198],[2,2,3],[50,35,3]])
key_list = np.array([[2,2,3],[255,243,198],[50,35,3]])
MagicFunction(value_list,key_list)
#result = [[0,1,0,2]] which has the same length as value_list
研究后,我在网上看到的解决方案并不是我所要求的,我相信,任何帮助都将不胜感激! 我有这个蛮力的代码可以提供结果,但我什至不想在我的实际数据大小上对其进行测试
T = np.zeros((len(value_list)), dtype = np.uint32)
for i in range(len(value_list)):
for j in range(len(key_list)):
if sum(value_list[i] == key_list[j]) == 3:
T[i] = j
答案 0 :(得分:1)
问题是如何使它效率不低。我看到两种方法
使用字典,以便快速查找。 numpy
数组是可变的,因此不可散列,因此您必须将其转换为例如元组以用于字典。
使用广播以矢量化方式检查value_list
中的每个“键”是否key_list
。这至少将for循环带出了Python,但是您仍然必须将每个值与每个键进行比较。
我也将在这里假设key_list
仅具有唯一的“键”。
这是第一种方法:
value_list = np.array([[2,2,3],[255,243,198],[2,2,3],[50,35,3]])
key_list = np.array([[2,2,3],[255,243,198],[50,35,3]])
key_map = {tuple(key): i for i, key in enumerate(key_list)}
result = np.array([key_map[tuple(value)] for value in value_list])
result # array([0, 1, 0, 2])
这是第二个:
result = np.where((key_list[None] == value_list[:, None]).all(axis=-1))[1]
result # array([0, 1, 0, 2])
哪种方法更快可能取决于key_list
和value_list
的大小。我会为您选择两种典型大小的阵列。
编辑-如评论中所述,第二种解决方案似乎并不完全正确,但是我不确定是什么使它失败了。考虑使用第一种解决方案。
答案 1 :(得分:0)
假设:
value_list
的每个元素将出现在key_list
中(在某个位置或另一个位置)key_list
中仅第一匹配解决方案:
从两个数组中,我们创建3元组的视图。然后,我们在两个正交方向上广播这两个视图,然后检查广播数组上的元素方式是否相等。
import numpy as np
value_list = np.array([[2,2,3],[255,243,198],[2,2,3],[50,35,3]], dtype='uint8')
key_list = np.array([[2,2,3],[255,243,198],[50,35,3]], dtype='uint8')
# Define a new dtype, describing a "structure" of 3 uint8's (since
# your original dtype is uint8). To the fields of this structure,
# give some arbitrary names 'first', 'sec', and 'third'
dt = np.dtype([('first', np.uint8, 1),('sec', np.uint8, 1),('third', np.uint8, 1)])
# Now view the arrays as 1-d arrays of 3-tuples, using the dt
v_value_list = value_list.view(dtype=dt).reshape(value_list.shape[0])
v_key_list = key_list.view(dtype=dt).reshape(key_list.shape[0])
result = np.argmax(v_key_list[:,None] == v_value_list[None,:], axis=0)
print (result)
输出:
[0, 1, 0, 2]
注释:
尽管这是一个纯粹的numpy解决方案,没有任何可见的循环,但是它可能具有隐藏的低效率,因为与value_list
的每个元素和key_list
的每个元素都匹配基于循环的搜索会在第一个成功匹配时立即停止。所获得的任何优势将取决于key_list
中key_list
的实际大小以及成功匹配发生的位置。随着key_list
的规模不断扩大,麻木的优势可能会受到侵蚀,尤其是如果成功的匹配主要发生在key_list
的较早部分。
我们正在创建的视图实际上是numpy结构化数组,其中视图的每个元素都是两个int
的结构。我还没有探讨的一个有趣的问题是,当numpy将一个结构与另一个结构进行比较时,是否对结构中的每个字段进行比较,还是使第一个失败字段的字段比较短路?结构?任何此类短路都可能暗示该结构化阵列解决方案具有少量额外优势。