簡體   English   中英

將索引和數據放入dict

[英]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]

希望能正確理解這個問題。

如果data1data2具有至少一個相等的尺寸,則可以垂直水平堆疊d1d2 ,然后對堆疊的陣列進行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))

您需要預先知道data1data2的大小,以分配d數組,但不需要同時將向量保留在內存中,一旦填充d的第一部分,您可以在加載data2之前刪除data1 我計算上述距離的方式,如(ab)**2 = a*a + b*b -2*a*b ,比你的方法更有效,特別是如果cols很大。

現在,您可以對數組d排序,並將其映射到兩個數組的行,例如@Developer的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM