我有一个从数据库读取的 pandas 表,它包含协方差矩阵(数字是随机的,因此它不是正半定义)。我想要一种从 pandas 表构建 numpy 矩阵的快速方法。
我有熊猫桌
索引1 | 索引2 | var |
---|---|---|
苹果 | 苹果 | 1 |
苹果 | 橙色 | 1 |
橙色 | 橙色 | 0.5 |
柠檬 | 柠檬 | 1.2 |
橙色 | 柠檬 | -0.5 |
苹果 | 柠檬 | -0.8 |
预期结果
[[1.2, -0.5, -0.8], [-0.5, 0.5, 1.0], [-0.8, 1.0, 1.0]]
下面是我尝试过的示例代码,但速度不是很快。
import numpy as np
import pandas as pd
pd_cov = pd.DataFrame([['apple', 'apple', 1], ['apple', 'orange', 1], ['orange', 'orange', 0.5], ['lemon', 'lemon', 1.2], ['orange', 'lemon', -0.5], ['apple', 'lemon', -0.8]], columns = ['index1', 'index2', 'var'])
def cov_obt(x,y):
try:
return(float(pd_cov_ind.loc[x, y]))
except:
return(float(pd_cov_ind.loc[y, x]))
ind = list(set(pd_cov['index1']))
pd_cov_ind = pd_cov.set_index(['index1', 'index2'])
np.array([[cov_obt(x,y) for y in ind] for x in ind])
这是一种方法:
import pandas as pd
import numpy as np
m = pd_cov.pivot_table(index='index1', columns='index2',
sort=False, fill_value=0).to_numpy()
m = m + m.T - np.tril(m)
m
array([[ 1. , 1. , -0.8],
[ 1. , 0.5, -0.5],
[-0.8, -0.5, 1.2]])
解释
df.pivot_table
旋转数据,将 sort
参数设置为 False
(维持顺序),将 fill_value
设置为 0
(第 2 步所需)。链接 to_numpy
并分配给变量 m
。m
),上面的三角形按预期填充,下面的三角形仍然填充零。我们可以通过添加 m
和 m.T
(其转置版本)来“复制”上三角形的值。由于对角线将以这种方式加倍,因此作为最后一步,我们需要减去对角线归零,我们可以通过应用 np.tril
来检索它。