RCV到矩阵

时间:2017-10-26 16:45:34

标签: python pandas numpy matrix

我的数据看起来像这样

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数据框快速将其快速地转换为正确的行和列索引数据框?

3 个答案:

答案 0 :(得分:2)

# apt install dh-autoreconf

致电pivotnp.fmax

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