簡體   English   中英

如何根據子列表[0]中的模式加速分割子列表列表的過程?

[英]How to accelerate a process to divide a list of sublists, based on a pattern in sublist[0]?

我有2個int和稀疏矩陣列表:
list_index = [1,1,2,3,3,4,4,5]
matrix_user = [sparse1, sparse2, sparse3, sparse4, sparse5, sparse6]

我想要一個子列表列表,每個子列表由一個int列表和一個稀疏矩陣組成:

[ [[1,1,2,3,3], [sparse1, sparse2, sparse3, sparse4]] ,
  [[4,4,5],     [sparse5, sparse6]] ,
  ... ,
  ]

長度為~90(稍后並行運行),每個sublist[0]包含非重疊值。

要將2個輸入列表分成90個部分,我將執行以下操作:

# cut the data into chunk to run in parallel
list_index  = dfuser['idx'].tolist()
matrix_user = encoder.fit_transform(dfuser[['col1','col2']].values)
sizechunk   = 90
sizelist    = int(len(list_index)/sizechunk)
if len(list_index)%sizechunk!=0 : sizelist += 1

list_all = []
for i in range(sizechunk) :
    if i*sizelist > len(list_index) : continue
    if (i+1)*sizelist < len(list_index) : list_all.append(  [list_index[i*sizelist:(i+1)*sizelist] , matrix_user_encoded.tocsr()[i*sizelist:(i+1)*sizelist] ]  )
    else : list_all.append( [list_index[i*sizelist:] , matrix_user_encoded.tocsr()[i*sizelist:] ])

這給了我一個90塊的列表:

[ [[1,1,2,3],[sparse1, sparse2, sparse3]] ,
  [[3,4,4,5],[sparse4, sparse5, sparse6]] ,
  ... ,
  ]

然后我過濾以便每個子列表具有不同的索引值:

i=0
size_list = len(list_all)
while i<size_list-1 :
    last_elem = list_all[i][0][len(list_all[i][0])-1]
    first_elem = list_all[i+1][0][0]
    first_sparse = list_all[i+1][1][0]
    while first_elem==last_elem :
        list_all[i][0].append(first_elem)
        list_all[i][1] = sp.vstack((list_all[i][1],first_sparse))
        list_all[i+1][0] = list_all[i+1][0][1:]
        list_all[i+1][1] = list_all[i+1][1][1:]
        if len(list_all[i+1][0])==0 :
            list_all.remove(list_all[i+1])
            size_list -= 1
            if i+1==size_list : break
        first_elem = list_all[i+1][0][0]
    i +=1

它有效,但由於我有很多輸入(約18億條目),需要6個小時!

我需要我的程序在不到2小時內運行,因為它需要每天多次調用。 是否存在python命令來削減我的2個列表,具體取決於第一個子列表的模式?

謝謝您的幫助!

編輯:運行的示例:

from scipy.sparse import csr_matrix

list_index = [0,0,1,2,2,3,4,5,5,6,6,7,7,7,8]
arr = np.random.random(size=(len(list_index), 5))
arr[arr < .7] = 0
matrix_user = csr_matrix(arr)
chunksize = 4

查看您可以使用的矩陣:

print(pd.SparseDataFrame(matrix_user))

經過多次改進后,我找到了解決方案:不是將2個輸入列表切割成90個部分,然后按順序過濾每個子列表具有不同的索引值,我為list_index提取所有可能的組合,然后切割成90個塊。

matrix_user = encoder.fit_transform(dfuser[['col1','col2']].values)

list_part_index = []
list_unique = list(dfuser.idx.unique())
for elem in list_unique : 
    list_part_index.append(dfuser[dfuser['idx']==elem].index[0])


nb_jump = int(len(list_unique)/90)
list_index = dfuser['idx'].tolist()
list_all = []
last_elem = list_part_index[0]
for elem in range(0, len(list_part_index),nb_jump) :
    if list_part_index[elem]>0  :
        list_all.append(  [list_index[last_elem:list_part_index[elem]] , matrix_user_encoded.tocsr()[last_elem:list_part_index[elem]] ]  )
    last_elem = elem
list_all.append(  [list_index[last_elem:] , matrix_user_encoded.tocsr()[last_elem:] ]  )   

我的程序現在運行22分鍾!

暫無
暫無

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

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