我的数据看起来像这样
Row_idx Column_idx Value
AA AA 1
AA BB 2
AA CC 3
BB BB 1
BB CC 4
CC CC 1
df=pd.DataFrame({'Row_idx':['AA','AA','AA','BB','BB','CC'],'Column_idx':['AA','BB','CC','BB','CC','CC'],'Value':[1,2,3,1,4,1]})
表示协方差矩阵的上半部分
AA BB CC
AA 1 2 3
BB 1 4
CC 1
如何才能最有效地将数据再次转换为完整的矩阵。 数据从文件读入数据帧并有几十万行,因此我想避免使用一些嵌套循环方法。
最终我需要这个作为np.array
1 2 3
2 1 4
3 4 1
我正在考虑使用numpy的triu软件包来完成矩阵,但是如何从RCV数据框快速将其快速地转换为正确的行和列索引数据框?
答案 0 :(得分:2)
# apt install dh-autoreconf
df
Column_idx Row_idx Value
0 AA AA 1
1 BB AA 2
2 CC AA 3
3 BB BB 1
4 CC BB 4
5 CC CC 1
在这种情况下,你也可以做(thanks, B. M.):
x = df.pivot('Row_idx', 'Column_idx', 'Value').values
np.fmax(x, x.T)
array([[ 1., 2., 3.],
[ 2., 1., 4.],
[ 3., 4., 1.]])
最终得到相同的结果,因为你正在处理三角矩阵。
答案 1 :(得分:1)
似乎Value
列保持的是上三角形元素。因此,要创建完整的矩阵/数组,我们可以使用一些掩码 -
def full_tri(v): # v is array holding values to be assigned into o/p
n = int(np.sqrt(len(v)*2)) # size of squared output array
out = np.empty((n,n),dtype=v.dtype)
r = np.arange(n)
m = r[:,None] <= r
out[m] = v
out.T[m] = v
return out
示例运行 -
In [757]: df
Out[757]:
Column_idx Row_idx Value
0 AA AA 1
1 BB AA 2
2 CC AA 3
3 BB BB 1
4 CC BB 4
5 CC CC 1
In [758]: full_tri(df.Value.values)
Out[758]:
array([[1, 2, 3],
[2, 1, 4],
[3, 4, 1]])
运行时测试
其他方法 -
# @cᴏʟᴅsᴘᴇᴇᴅ's soln
def pivot_fmax(df):
x = df.pivot('Row_idx', 'Column_idx', 'Value').values
return np.fmax(x, x.T)
# @B. M.'s soln
def pivot_fillna(df):
M=df.pivot(*df.columns)
M.fillna(M.T,inplace=True)
return M.values
更大数据集上的计时 -
In [791]: N = 1000 # size of testing dataset
...: r,c = np.triu_indices(N)
...: df = pd.DataFrame(np.c_[r,c,np.random.randint(11,99,(len(r)))])
...: df.columns = [['Row_idx', 'Column_idx', 'Value']]
...:
In [792]: %timeit pivot_fmax(df)
...: %timeit pivot_fillna(df)
...: %timeit full_tri(df.Value.values)
...:
10 loops, best of 3: 89.7 ms per loop
10 loops, best of 3: 96.5 ms per loop
100 loops, best of 3: 4.19 ms per loop
In [793]: N = 2000 # size of testing dataset
...: r,c = np.triu_indices(N)
...: df = pd.DataFrame(np.c_[r,c,np.random.randint(11,99,(len(r)))])
...: df.columns = [['Row_idx', 'Column_idx', 'Value']]
...:
In [794]: %timeit pivot_fmax(df)
...: %timeit pivot_fillna(df)
...: %timeit full_tri(df.Value.values)
...:
1 loop, best of 3: 412 ms per loop
1 loop, best of 3: 425 ms per loop
100 loops, best of 3: 18.6 ms per loop
答案 2 :(得分:1)
要保留DataFrame,只需执行以下操作:
M=df.pivot(*df.columns)
M.fillna(M.T,inplace=True)
# Column_idx AA BB CC
# Row_idx
# AA 1.0 2.0 3.0
# BB 2.0 1.0 4.0
# CC 3.0 4.0 1.0