我试图避免在以下代码中使用循环,因为它很慢。我首先列出了标签列表和指标列表,其长度与几百万相同。然后我想制作一个对称的NxN矩阵,其中N是唯一标签值的数量(大约100)。矩阵包含度量的比较。具体来说,度量是一个列表列表,我想计算子列表中匹配元素的数量,并用该值更新输出矩阵。目前的代码是:
matrix = {}
for i,value_i in enumerate(labels):
for j,value_j in enumerate(labels):
if i >= j:
matrix[(value_i,value_j)] = matrix.get((value_i,value_j), 0)
+ np.count_nonzero(metrics[i]==metrics[j])
if i != j:
matrix[(value_j,value_i)] = matrix[(value_i,value_j)]
我想做列表理解之类的事情,但也想要一本字典因为我经常更新。对于上下文,我已经从更精细的代码here
中删除了这个------- --------更新
授予@piRSquared建议使用numba的答案。增益来自于使用这个包而不是使用数组而不是dict。为了比较,以下是慢1.29倍。
f, u = pd.factorize(labels)
mx = f.max() + 1
matrix = np.zeros((mx, mx), np.int64)
for i in f:
for j in f:
if i >= j:
matrix[i, j] = matrix[i, j]
+ np.count_nonzero(metrics[i] == metrics[j])
if i != j:
matrix[j, i] = matrix[i, j]
df = pd.DataFrame(matrix, u, u)
答案 0 :(得分:1)
我还在弄乱这个。这仍然是一个循环但我使用numba
来加快速度。我将最终以更多信息充实这篇文章。但是,我现在想给你一些合作的东西。
我还有其他想法可以加快速度。
from string import ascii_uppercase
import numpy as np
import pandas as pd
from numba import njit
@njit
def fill(f, metrics):
mx = f.max() + 1
matrix = np.zeros((mx, mx), np.int64)
for i in f:
for j in f:
if i >= j:
row_i = metrics[i]
row_j = metrics[j]
matrix[i, j] = matrix[i, j] + (row_i == row_j).sum()
if i != j:
matrix[j, i] = matrix[i, j]
return matrix
def fill_from_labels(labels, metrics):
f, u = pd.factorize(labels)
matrix = fill(f, metrics)
return pd.DataFrame(matrix, u, u)
df = fill_from_labels(labels, metrics)