我的数据格式如下:
['FACTOR_1','FACTOR_2",'VALUE"]
['A' ,'A' ,2.0 ]
['A' ,'B' ,3.0 ]
['A' ,'C' ,2.2 ]
['A' ,'D' ,2.6 ]
['B' ,'A' ,2.6 ]
['B' ,'B' ,1.0 ]
['B' ,'C' ,6.0 ]
['B' ,'D' ,7.7 ]
['C' ,'A' ,2.1 ]
....
['D' ,'D' ,2.6 ]
它位于数据框中,但我还是转换为numpy数组。
我希望将其转换为两个因素的矩阵。
我自己编码了,但我目前的做法是非常缓慢且低效,我有一个嵌套循环并且正在搜索因子的索引:
no_of_factors = np.size(np.unique(cov_data['FACTOR_1']))
factors = np.unique(cov_data['FACTOR_1'])
cov_matrix = np.zeros((no_of_factors, no_of_factors))
i = 0
for factor_1 in factors:
factor_indices = np.where(cov_data['FACTOR_1'] == factor_1)[0].tolist()
j = 0
for factor_2 in factors:
factor_2_index = np.where(cov_data['FACTOR_2'][factor_indices] == factor_2)[0].tolist()
if np.size(factor_2_index) > 1:
self.log.error("Found duplicate factor")
elif np.size(factor_2_index) == 0:
var = 0
else:
factor_2_index = factor_2_index[0]
var = cov_data['VALUE'][factor_2_index]
cov_matrix[i][j] = var
j += 1
i += 1
令人讨厌的是,数据也不完美,并且每个因素都没有值,例如因子C可能只有A和B的值而D可能会丢失,因此检查并设置为0
答案 0 :(得分:1)
您的代码中存在错误,我使用sub_data
数组行进行了更正。我还以一些显而易见的方式简化了代码:
def foo(cov_data):
factors = np.unique(cov_data['FACTOR_1'])
no_of_factors = factors.shape[0]
cov_matrix = np.zeros((no_of_factors, no_of_factors))
for i,factor_1 in enumerate(factors):
factor_indices = np.where(cov_data['FACTOR_1'] == factor_1)[0]
sub_data = cov_data[factor_indices]
for j,factor_2 in enumerate(factors):
factor_2_index = np.where(sub_data['FACTOR_2'] == factor_2)[0]
if factor_2_index.shape[0]==1:
cov_matrix[i, j] = sub_data['VALUE'][factor_2_index[0]]
elif factor_2_index.shape[0] ==0:
pass
else:
self.log.error("Found duplicate factor")
return cov_matrix
如果我从列表中制作结构化数组
cov_data = np.array([tuple(i) for i in factors], dtype=[('FACTOR_1','|U1'),('FACTOR_2','|U1'),('VALUE','f')])
我得到了cov_matrix
:
[[ 2. 3. 2.20000005 2.5999999 ]
[ 2.5999999 1. 6. 7.69999981]
[ 2.0999999 0. 0. 0. ]
[ 0. 0. 0. 2.5999999 ]]
我还没有使用过这种特征矩阵,但我认为它是学习scikit-learn
等代码的最重要的任务。
有时sklearn
人制作稀疏矩阵。这是一种简单的方法:
features1, ind1 = np.unique(cov_data['FACTOR_1'], return_inverse=True)
features2, ind2 = np.unique(cov_data['FACTOR_2'], return_inverse=True)
values = cov_data['VALUE']
from scipy import sparse
M = sparse.coo_matrix((values,(ind1, ind2)))
return_inverse
给出了原始数组中每个唯一值的索引。因此实际上它将字符串转换为行或列索引。
此矩阵M.A
的密集版本是相同的。
print(M)
显示索引值三元组:
(0, 0) 2.0
(0, 1) 3.0
(0, 2) 2.2
(0, 3) 2.6
(1, 0) 2.6
(1, 1) 1.0
(1, 2) 6.0
(1, 3) 7.7
(2, 0) 2.1
(3, 3) 2.6
这个计算存在一些粗略的边缘,例如如何处理重复项(添加值),features
的顺序以及如果一个列表不像另一个列表那样完成该怎么办。 unique
对它们进行排序。
从索引构造密集矩阵也很容易:
cov_matrix = np.zeros((len(features1), len(features2)))
cov_matrix[ind1, ind2] = values
print(cov_matrix)
(同样,它可能无法正确处理重复)。