Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 矢量化numpy 1-d重新分类_Python_Arrays_Numpy_Classification_Vectorization - Fatal编程技术网

Python 矢量化numpy 1-d重新分类

Python 矢量化numpy 1-d重新分类,python,arrays,numpy,classification,vectorization,Python,Arrays,Numpy,Classification,Vectorization,我有一个大的numpy 1-d,包含大约700000个类。此外,我还有另一个类似大小的数组,其中包含类的新值 示例数组 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,

我有一个大的numpy 1-d,包含大约700000个类。此外,我还有另一个类似大小的数组,其中包含类的新值

示例数组

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类分配给相同的新类编号等


由于我正在使用大型阵列,我希望重新分类功能能够矢量化。

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

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)
您可以使用重新标记您的类。对于您的示例数据:

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]

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

70000个项目的数组?它一点也不大。尝试使用循环实现。当你有它的权利,如果你不满意的表现,张贴在这里。对不起,应该是700000。已经在研究循环方法了!这将占用大约2.7MB的内存。仍然没有那么大。在您的示例中,1变为0,0变为1。这怎么不是一个无限循环呢?我只是想指出0和1(以及2和6)是同一个类。他们被分配到哪个新的班级号并不重要。对于一个代码示例,您可以查看未分割的方法。谢谢,明天我将测试我的方法,并将其与您的结果进行比较!你的方法出错了,所以我还没有测试出来!即使使用非连续值,此方法也会正确地重新标记类。你确定他们需要连续吗?@Wilmar-这是为了最好的表现。在我的代码中,
mapping
将是一个长度为
N
的数组,因此如果输入有数十亿未使用的类,那么它将是一个比需要的数组大得多的数组,因此效率低下。几个小间隙不会对性能产生太大影响。但是剩余的
n_
也包括未使用的类,而且
映射[A]
也很可能不是连续的。