[英]put index and data to dict
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個最近的向量)。
如何做呢? 我需要使用字典嗎?
更新:
我不能堆疊data1和data2,因為那樣就不適合RAM。 我使用numpy.memmap按塊(1個塊=數據)讀取了我的大數組。
例如,這可以工作,但僅適用於小尺寸。所以我需要通過塊迭代地處理數據。
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:對象不正確
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]
希望能正確理解這個問題。
如果data1
和data2
具有至少一個相等的尺寸,則可以垂直或水平堆疊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]
我沒有測試代碼,所以可能是錯誤的,但我希望它足夠清楚,那就做你想要的
這是我們的解決方案:
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
如果您有內存問題,可以執行以下操作:
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
數組,但不需要同時將向量保留在內存中,一旦填充d
的第一部分,您可以在加載data2
之前刪除data1
。 我計算上述距離的方式,如(ab)**2 = a*a + b*b -2*a*b
,比你的方法更有效,特別是如果cols
很大。
現在,您可以對數組d
排序,並將其映射到兩個數組的行,例如@Developer的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.