我正在寻找加快(或替换)数据分组算法的方法。
我有一个 numpy 数组列表。我想生成一个新的 numpy 数组,使得对于原始数组中相同的每个索引处,此数组的每个元素都是相同的。(对于不是这种情况的地方则不同)
这听起来比较别扭,因此举个例子:
# Test values:
values = [
np.array([10, 11, 10, 11, 10, 11, 10]),
np.array([21, 21, 22, 22, 21, 22, 23]),
]
# Expected outcome: np.array([0, 1, 2, 3, 0, 3, 4])
# * *
请注意,期望结果中我标记的元素(索引为0和4)具有相同的值(
0
),因为原始的两个数组也相同(即10
和21
)。索引为3和5的元素 (3
) 同理。算法需要处理任意数量的(大小相等的)输入数组,并且还要返回每个结果数字对应的原始数组的值。 (因此,对于这个例子,“3”指的是
(11, 22)
。)以下是我的当前算法:
import numpy as np
def groupify(values):
group = np.zeros((len(values[0]),), dtype=np.int64) - 1 # Magic number: -1 means ungrouped.
group_meanings = {}
next_hash = 0
matching = np.ones((len(values[0]),), dtype=bool)
while any(group == -1):
this_combo = {}
matching[:] = (group == -1)
first_ungrouped_idx = np.where(matching)[0][0]
for curr_id, value_array in enumerate(values):
needed_value = value_array[first_ungrouped_idx]
matching[matching] = value_array[matching] == needed_value
this_combo[curr_id] = needed_value
# Assign all of the found elements to a new group
group[matching] = next_hash
group_meanings[next_hash] = this_combo
next_hash += 1
return group, group_meanings
请注意,表达式
value_array [matching] == needed_value
对于每个单独的索引都会被评估多次,这就是速度慢的原因所在。我不确定我的算法是否可以进一步加速,但我也不确定它是否是最优算法。有更好的方法吗?
np.ravel_multi_index
是做什么的?(文档对我来说不是很清楚。)为什么要在arr.max(1)+1
上调用它? - acdr_,values_elems = np.unique(input_string,return_inverse=True)
来为我们自己创建数字标签,这些标签将对应于values
中的元素。在此过程中,您可能需要使用.ravel()
和重塑操作。 - Divakar[np.unique(v,return_inverse=True)[1] for v in values]
而不是values
的确解决了“其他数据类型”的问题。我接受了这个答案(尽管我也喜欢 Eelco 的答案),因为它不需要单独的包,并且 timeit 的结果也很好。 - acdr