Python 矢量化numpy 1-d重新分类
我有一个大的numpy 1-d,包含大约700000个类。此外,我还有另一个类似大小的数组,其中包含类的新值 示例数组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,
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]
也很可能不是连续的。