X是包含100000
相等大小(500个元素)位向量的文本文件(即每行是500个元素的向量)。我正在使用下面的代码生成一个邻接矩阵(100000 X 100000),但它没有优化,非常耗时。我怎样才能改善这一点。
import numpy as np
import scipy.spatial.distance
readFrom = "vector.txt"
fout = open("adjacencymatrix.txt","a")
X = np.genfromtxt(readFrom, dtype=None)
for outer in range(0,100000):
for inner in range(0,100000):
dis = scipy.spatial.distance.euclidean(X[outer],X[inner])
tmp += str(dis)+" "
tmp += "\n"
fout.write(tmp)
fout.close()
谢谢。
答案 0 :(得分:3)
对代码进行了一些小的优化(我假设你使用的是Python 2.x):
import numpy as np
import scipy.spatial.distance
X = np.genfromtxt("vector.txt", dtype=None)
fout = open("adjacencymatrix.txt", "a")
for outer in xrange(0, 100000):
fout.write(" ".join(str(scipy.spatial.distance.euclidean(X[outer], X[inner])) for inner in xrange(0, 100000)) + "\n")
fout.close()
我不建议在编写之前预先计算整个矩阵 - 虽然这样做可以让我们利用问题的模拟并迭代只有一半的元素,但它会消耗一个很多记忆。我坚持你所拥有的 - 每一行都是在计算后立即编写的。
这里真正的问题是输入数据很大,距离计算将执行100,000 x 100,000 = 10,000'000,000次,并且没有多少微优化会改变这一点。您确定必须计算整个矩阵吗?
答案 1 :(得分:1)
编辑:在更好地理解问题后完成重写。鉴于数据的大小等,这个很棘手。到目前为止,我在加速时得到了最好的结果:
import time
import numpy as np
from scipy import spatial
import multiprocessing as mp
pool = mp.Pool(4)
test_data = np.random.random(100000*500).reshape([100000,500])
outfile = open('/tmp/test.out','w')
def split(data,size):
for i in xrange(0, len(data), size):
yield data[i:i+size]
def distance(vecs):
return spatial.distance.cdist(vecs,test_data)
chunks = list(split(test_data,100))
for chunk in chunks:
t0 = time.time()
distances = spatial.distance.cdist(chunk,test_data)
outfile.write(' '.join([str(x) for x in distances]))
print 'estimated: %.2f secs'%((time.time()-t0)*len(chunks))
所以我尝试平衡数据集的每个块的大小与内存开销。这让我估计完成了大约6,600秒,或者大约110分钟。你可以看到我也开始看到我是否可以使用多处理池进行并行化。我的策略是异步处理每个块并将它们保存到不同的文本文件中,然后将文件连接起来,但我必须重新开始工作。
答案 2 :(得分:0)
(如果您使用的是Python 2.x,请使用xrange
代替range
。)
要进行计算,您可以使用:
diff_matrix = numpy.subtract.outer(X, X)
result = numpy.sqrt(numpy.abs(diff_matrix))
# output the result.
请注意,要存储100,000 {100,000} double
矩阵,您需要74.5 GB内存,并且可能是文本输出文件大小的两倍。你真的需要整个矩阵吗? (您也可以并行化计算,但这需要的不仅仅是numpy。)
答案 3 :(得分:0)
我有一种预感,即使用矩阵运算可以在没有显式python循环的情况下计算距离矩阵。
X
及其转置的外积似乎很有希望,因为它执行每对向量的内积并将结果留在得到的100.000 x 100.000矩阵的每个单元格中,并且内积非常接近与欧氏距离(或其正方形)有关。
所以我想这是一个调整问题,以获得两个向量之间的欧氏距离,而不是内部产品。我的直觉告诉我,复数可能在这里很有用。
也许一些更聪明的头脑可以在这里发光。