python - 高效地将 numpy 数组转换为矩阵

标签 python numpy scikit-learn

我有以下格式的数据:

['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/

相关文章:

python - 如何使用 H5py 在 python 3 中正确打开、读取和保存单个文件

python - 如何在sklearn中得到交叉验证的预测结果

python - 使用 scikit-learn PCA.score() 时出错

python - 无法 pip 安装 Tensorflow 'msvcp140_1.dll' 缺失

python - 如何从列表中分解一个数字与另一个数字?

python - 不规则间距堆积点的计算方法

python - 并行训练多个不同的 sklearn 模型

python - 为什么这个 for 循环在删除列表中的所有项目之前停止?

python - 无法在 python 中打开图像文件

python - 绘制周期轨迹