使用另一个列表python从列表创建索引值数组

时间:2019-03-03 02:31:33

标签: python image numpy indexing

我有一个值数组以及另一个要为其创建索引的数组。 例如:

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

2 个答案:

答案 0 :(得分:1)

问题是如何使它效率不低。我看到两种方法

  1. 使用字典,以便快速查找。 numpy数组是可变的,因此不可散列,因此您必须将其转换为例如元组以用于字典。

  2. 使用广播以矢量化方式检查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_listvalue_list的大小。我会为您选择两种典型大小的阵列。

编辑-如评论中所述,第二种解决方案似乎并不完全正确,但是我不确定是什么使它失败了。考虑使用第一种解决方案。

答案 1 :(得分:0)

假设:

  1. value_list的每个元素将出现在key_list 中(在某个位置或另一个位置)
  2. 我们对key_list中仅第一匹配
  3. 的索引感兴趣

解决方案:

从两个数组中,我们创建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]

注释:

  1. 尽管这是一个纯粹的numpy解决方案,没有任何可见的循环,但是它可能具有隐藏的低效率,因为与value_list的每个元素和key_list的每个元素都匹配基于循环的搜索会在第一个成功匹配时立即停止。所获得的任何优势将取决于key_listkey_list的实际大小以及成功匹配发生的位置。随着key_list的规模不断扩大,麻木的优势可能会受到侵蚀,尤其是如果成功的匹配主要发生在key_list的较早部分。

  2. 我们正在创建的视图实际上是numpy结构化数组,其中视图的每个元素都是两个int的结构。我还没有探讨的一个有趣的问题是,当numpy将一个结构与另一个结构进行比较时,是否对结构中的每个字段进行比较,还是使第一个失败字段的字段比较短路?结构?任何此类短路都可能暗示该结构化阵列解决方案具有少量额外优势。