data = np.random.rand(rows,cols)
vec= np.random.rand(1,cols)
d = ((data-vec)**2).sum(axis=1) # compute distances
ndx = d.argsort()
比我先拿k
ndx[:k]
但如果有
d1 = ((data1-vec)**2).sum(axis=1) # compute distances
ndx1 = d1.argsort()
d2 = ((data2-vec)**2).sum(axis=1) # compute distances
ndx2 = d2.argsort()
我需要连接ndx1 + ndx2的值+索引并按值排序(从2k向量中取k个最近的向量)。
怎么做?我需要使用dict吗?
更新
我无法堆叠data1和data2,因为它不适合RAM。我使用块的numpy.memmap读取我的大数组(1 chunk = data)。
例如,这可行,但仅适用于小尺寸。所以我需要通过块迭代地处理数据。
import numpy as np
import time
rows = 10000
cols = 1000
batches = 5
k= 10
fp = np.memmap('C:/memmap_test', dtype='float32', mode='w+', shape=(rows*batches,cols))
vec= np.random.rand(1,cols)
t0= time.time()
d = ((fp-vec)**2).sum(axis=1) # compute distances
ndx = d.argsort()
print (time.time()-t0)
print ndx[:k]
这种方法不起作用:
ValueError:object is alighn
t0= time.time()
d = np.empty((rows*batches,))
for i in range(batches):
d[i*rows:(i+1)*rows] = (np.einsum('ij,ij->i', fp[i*rows:(i+1)*rows], fp[i*rows:(i+1)*rows]) + np.dot(vec, vec) -
2 * np.dot(fp[i*rows:(i+1)*rows], vec))
print (time.time()-t0)
这似乎有用
t0= time.time()
d = np.empty((rows*batches,))
for i in range(batches):
d[i*rows:(i+1)*rows] = ((fp[i*rows:(i+1)*rows]-vec)**2).sum(axis=1)
ndx = d.argsort()
print (time.time()-t0)
print ndx[:k]
答案 0 :(得分:3)
希望能够正确理解这个问题。
如果data1
和data2
至少有一个维度相等,您可以堆叠vertically或horizontally d1
和d2
然后argsort
堆叠数组。
这样排序将在两个数组的所有元素上完成,但你不知道哪一个是原始数组。
我不认为dict是要走的路,如果不是因为dict没有被命令。
我想到的一种方法或多或少是这样的:
#read the first batch and compute distances
# save the first k indeces and values
masterindex = d.argsort()[:k]
mastervalue = d[masterindex]
for i in (all the other batches):
#read the following batch and compute distances
tempindex = d.argsort()[:k]
tempvalue = d[tempindex]
# get the tempindex as absolute position with respect to the whole file
tempindex += n_rows_already_read # by previous batches
#stack the indeces and value arrays
masterindex = np.concatenate([masterindex,tempindex])
mastervalue = np.concatenate([mastervalue,tempvalue])
# argsort the concatenated values, then save the new sorted
# values and indeces
indx = mastervalue.argsort()[:k]
masterindex = masterindex[indx]
mastervalue = mastervalue[indx]
我还没有对代码进行测试,因此可能会出错,但我希望它足够清晰并且可以满足您的需求
答案 1 :(得分:2)
以下是我们的解决方案:
import numpy as np
rows1,rows2,cols = 1000,600,7
data1 = np.random.rand(rows1,cols)
data2 = np.random.rand(rows2,cols)
data = np.vstack((data1,data2)) #stacking data
vec = np.random.rand(1,cols)
d = ((data-vec)**2).sum(axis=1) #compute distances
ndx = d.argsort()
k = 30
sdx = ndx[:k] #selected k indices of nearest points
f = (sdx<rows1) #masking
idx1 = sdx[f] #indices from data1
idx2 = sdx[~f]-rows1 #indices from data2
答案 2 :(得分:2)
如果您遇到内存问题,可以执行以下操作:
data1 = np.random.rand(rows1, cols)
data2 = np.random.rand(rows2, cols)
vec = np.random.rand(cols)
d = np.empty((rows1 + rows2,))
d[:rows1] = (np.einsum('ij,ij->i', data1, data1) + np.dot(vec, vec) -
2 * np.dot(data1, vec))
d[rows1:] = (np.einsum('ij,ij->i', data2, data2) + np.dot(vec, vec) -
2 * np.dot(data2, vec))
您需要预先知道data1
和data2
的大小,以分配d
数组,但您不需要同时将向量保留在内存中,您可以删除在加载data1
之前填充d
的第一部分后data2
{。}}。我计算距离的方式,如(a-b)**2 = a*a + b*b -2*a*b
,比你的方法更有效,特别是cols
很大。
您现在可以对数组d
进行排序,并将其映射到两个数组的行,例如就像@ Developer的回答一样。