我有以下格式的数据:
['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。
最佳答案
您的代码中有一个错误,我已使用 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
此计算有一些粗糙的边缘,例如如何处理重复项(添加值)、功能
的顺序以及如果一个列表不如另一个列表完整时该怎么办。 unique
对它们进行排序。
从索引构建稠密矩阵也很容易:
cov_matrix = np.zeros((len(features1), len(features2)))
cov_matrix[ind1, ind2] = values
print(cov_matrix)
(同样,它可能无法正确处理重复项)。
关于python - 高效地将 numpy 数组转换为矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38208555/