我将通过一个我想做的例子来简化我的问题(我正在使用的实际数据非常庞大)。
如果有一个3维稀疏数组对象可以输入x,y,z坐标以及要存储的数据,那么我的问题的解决方案将很简单。请注意,如果我不使用稀疏数组,我将遇到内存问题。让我们说我有一个阵列:
import numpy as np
from scipy.sparse import coo_matrix
arr=np.array([1,3,4,5],[0,6,7,8],[1,7,8,7]])
前3个条目是x,y,z。理想情况下,我想要一个稀疏矩阵 这会产生B [1,3,4] = 5和B [0,6,7] = 8等。现在我正在使用一个字典,其中x坐标是关键。 y和z将是稀疏数组坐标。所以它是这样的:
row=arr[:,1]
col=arr[:,2]
data=arr[:,3]
dic={}
### x here goes from only 0 to 1 in this simple example
for x in range(2):
bool=arr[:,0][arr[:,0]==x] ####### this step takes too long
###### now create sparse matrix for all data with
###### x value equal to the iterator
dic[x]=coo_matrix((data[bool], (row[bool],
col[bool])), shape=(1536, 32768)) ### this part ok
所以我记下的bool测试是占据90%的时间的步骤。这是因为我的阵列非常庞大。 理想情况下,我想直接将所有内容编入索引。
解决方案?
谢谢!
谢谢!
答案 0 :(得分:0)
这是另一种方法 -
out_shp = (10,10) # (1536, 32768) for your actual case
out_dic = {}
for i in np.unique(arr[:,0]):
RCD = arr[arr[:,0] == i,1:]
out_dic[i] = coo_matrix((RCD[:,2],(RCD[:,0],RCD[:,1])), shape=out_shp)
示例输入,输出 -
In [87]: arr
Out[87]:
array([[1, 3, 4, 5],
[0, 6, 7, 8],
[1, 7, 8, 7]])
In [88]: out_dic[0].toarray()
Out[88]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 8, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [89]: out_dic[1].toarray()
Out[89]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 7, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
这是另一种方法,它在进入循环之前根据第一列对数组进行排序,并简单地在循环内切片。这是一种专注于性能的方法,因为我们将在循环内进行较少的计算,因为这似乎是瓶颈。所以,我们会有另外一个实现 -
s_arr = arr[arr[:,0].argsort()] # Sorted array
unq,start_idx = np.unique(s_arr[:,0],return_index=1)
stop_idx = np.append(start_idx[1:],arr.shape[0])
out_shp = (10,10) # (1536, 32768) for your actual case
out_dic = {}
for i,u in enumerate(unq):
RCD = s_arr[start_idx[i]:stop_idx[i],1:] # Row-col-data
out_dic[u] = coo_matrix((RCD[:,2],(RCD[:,0],RCD[:,1])), shape=out_shp)