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

问题描述 投票:1回答:2

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

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
python image numpy indexing
2个回答
1
投票

问题是如何使这不是非常低效。我看到两种方法

  1. 使用字典,以便查找速度很快。 numpy数组是可变的,因此不可清除,因此您必须将它们转换为例如用于字典的元组。
  2. 使用广播以矢量化方式检查value_listkey_list中的每个“关键字”。这至少会带来for循环,但你仍然需要将每个值与每个键进行比较。

我将在这里假设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的大小。我想为你准备一些典型尺寸的阵列。

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


0
投票

假设:

  1. value_list的每个元素都将出现在key_list(在某个位置或其他位置)
  2. 我们对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]

笔记:

  1. 虽然这是一个没有任何可见循环的纯粹的numpy解决方案,但它可能隐藏了低效率,因为它将value_list的每个元素与key_list的每个元素相匹配,而基于循环的搜索在第一次成功匹配时巧妙地停止。获得的任何优势将取决于key_list的实际大小,以及成功匹配发生的位置,在key_list。随着key_list的规模增长,可能会对numpy优势产生一些影响,特别是如果成功的比赛主要发生在key_list的早期部分。
  2. 我们正在创建的视图实际上是numpy结构化数组,其中视图的每个元素都是两个int的结构。我还没有探讨的一个有趣的问题是,当numpy将一个结构与另一个结构进行比较时,它是否对结构中的每个字段进行了比较,或者是否在第一个失败的字段中对字段比较进行了短路。结构?任何这种短小的细节都可能意味着这种结构化阵列解决方案的一个小额外优势。
© www.soinside.com 2019 - 2024. All rights reserved.