矢量化numpy 1-d重新分类

时间:2016-11-16 10:07:41

标签: python arrays numpy classification vectorization

我有一个大的numpy 1-d包含大约700,000个类。另外,我有另一个类似大小的数组,它包含类的新值。

示例数组

original_classes = np.array([0,1,2,3,4,5,6,7,8,9,10,10])
new_classes = np.array([1,0,1,2,2,10,1,6,6,9,5,12])

所需的输出

>>> reclassify_function(original_classes, new_classes)
array([ 1,  1,  1,  1,  1, 12,  1,  1,  9, 12, 12])

困难在于有多种阶级关系。

原始类1应该获得0的新值,这意味着0和1是相等的类,并且所有出现的这些值都应该分配给相同的新类号。原始类2应归类为1,这意味着类2等于0级和1级。因此,原始类0-2应分配给相同的新类号等...

当我使用大型数组时,我希望将重分类函数进行矢量化。

2 个答案:

答案 0 :(得分:1)

您可以使用scipy.sparse.csgraph.connected_components重新标记您的课程。对于您的示例数据:

from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import connected_components

A = np.array([0,1,2,3,4,5, 6,7,8,9,10,10])
B = np.array([1,0,1,2,2,10,1,6,6,9,5 ,12])

N = max(A.max(), B.max()) + 1
weights = np.ones(len(A), int)
graph = csr_matrix((weights, (A, B)), shape=(N, N))
n_remaining, mapping = connected_components(graph, directed=False)
print mapping[A]

给出:

[0 0 0 0 0 1 0 0 0 2 1 1]

这些是重新标记的类。我相信你可以弄清楚如何根据输入数据来表达这些。注意为了获得最佳性能,“原始”和“新”类应该是没有间隙的单个连续整数范围。

答案 1 :(得分:0)

这不是矢量化解决方案,在我的笔记本电脑上花了大约一个小时。这会创建一个名为class_sets的集合列表;每一组都是等价类的集合。

original_classes = np.random.randint(0,20000,700000)
new_classes = np.random.randint(0,20000,700000)
pairs = zip(original_classes, new_classes)
class_sets = [set(next(pairs))]

for i,p in enumerate(pairs):
    ps = set(p)
    intsect = [ps.intersection(cs) for cs in class_sets]
    if any([ps.intersection(cs) for cs in class_sets]):
        index = np.argmax(intsect)
        class_sets[index] = class_sets[index].union(ps)
    else:
        class_sets.append(ps)