【问题标题】:Melt the Upper Triangular Matrix of a Pandas Dataframe融化 Pandas 数据框的上三角矩阵
【发布时间】:2016-03-28 19:50:01
【问题描述】:

给定一个如下形式的方形 pandas DataFrame:

   a  b  c
a  1 .5 .3
b .5  1 .4
c .3 .4  1

upper triangle如何融化得到如下形式的矩阵

 Row     Column    Value
  a        a       1
  a        b       .5 
  a        c       .3
  b        b       1
  b        c       .4
  c        c       1 

#Note the combination a,b is only listed once.  There is no b,a listing     

我对惯用的 pandas 解决方案更感兴趣,自定义索引器很容易手动编写...

提前感谢您的考虑和回复。

【问题讨论】:

    标签: python pandas numpy reshape melt


    【解决方案1】:

    首先我通过wherenumpy.triudf的较低值转换为NaN,然后stackreset_index并设置列名:

    import numpy as np
    
    print df
         a    b    c
    a  1.0  0.5  0.3
    b  0.5  1.0  0.4
    c  0.3  0.4  1.0
    
    print np.triu(np.ones(df.shape)).astype(np.bool)
    [[ True  True  True]
     [False  True  True]
     [False False  True]]
    
    df = df.where(np.triu(np.ones(df.shape)).astype(np.bool))
    print df
        a    b    c
    a   1  0.5  0.3
    b NaN  1.0  0.4
    c NaN  NaN  1.0
    
    df = df.stack().reset_index()
    df.columns = ['Row','Column','Value']
    print df
    
      Row Column  Value
    0   a      a    1.0
    1   a      b    0.5
    2   a      c    0.3
    3   b      b    1.0
    4   b      c    0.4
    5   c      c    1.0
    

    【讨论】:

    • 我唯一需要注意的是,如果您有任何 NaN 值要保留在上三角形中(stack 将全部删除)。如果是这种情况,您可能必须显式构建多索引,然后重新索引。
    • @jezrael 你如何从最后一个df 回到三角形的?我已经建立了三角矩阵,转换为长的,处理的,现在我想把它恢复成三角形,但是一些NAs 去上三角
    • @Sosi - 我认为需要像df = df.pivot('Row', 'Column', 'Value')这样的支点
    • @jezrael 谢谢。但是,这仍然会产生一个非三角矩阵。也许我会创建一个新线程并 ping 你
    • @Sosi - 没问题 :) pivot 总是对数据进行排序 :)
    【解决方案2】:

    从@jezrael 的解决方案构建,布尔索引将是一种更明确的方法:

    import numpy
    from pandas import DataFrame
    
    df = DataFrame({'a':[1,.5,.3],'b':[.5,1,.4],'c':[.3,.4,1]},index=list('abc'))
    print df,'\n'
    keep = np.triu(np.ones(df.shape)).astype('bool').reshape(df.size)
    print df.stack()[keep]
    

    输出:

         a    b    c
    a  1.0  0.5  0.3
    b  0.5  1.0  0.4
    c  0.3  0.4  1.0 
    
    a  a    1.0
       b    0.5
       c    0.3
    b  b    1.0
       c    0.4
    c  c    1.0
    dtype: float64
    

    【讨论】:

    【解决方案3】:

    同样基于@jezrael 的解决方案,这是一个版本,添加了一个函数来执行逆运算(从 xy 到矩阵),在我的情况下对协方差/相关矩阵很有用。

    def matrix_to_xy(df, columns=None, reset_index=False):
        bool_index = np.triu(np.ones(df.shape)).astype(bool)
        xy = (
            df.where(bool_index).stack().reset_index()
            if reset_index
            else df.where(bool_index).stack()
        )
        if reset_index:
            xy.columns = columns or ["row", "col", "val"]
        return xy
    
    
    def xy_to_matrix(xy):
        df = xy.pivot(*xy.columns).fillna(0)
        df_vals = df.to_numpy()
        df = pd.DataFrame(
            np.triu(df_vals, 1) + df_vals.T, index=df.index, columns=df.index
        )
        return df
    df = pd.DataFrame(
        {"a": [1, 0.5, 0.3], "b": [0.5, 1, 0.4], "c": [0.3, 0.4, 1]},
        index=list("abc"),
    )
    print(df)
    xy = matrix_to_xy(df, reset_index=True)
    print(xy)
    mx = xy_to_matrix(xy)
    print(mx)
    

    输出:

         a    b    c
    a  1.0  0.5  0.3
    b  0.5  1.0  0.4
    c  0.3  0.4  1.0
    
      row col  val
    0   a   a  1.0
    1   a   b  0.5
    2   a   c  0.3
    3   b   b  1.0
    4   b   c  0.4
    5   c   c  1.0
    
    row    a    b    c
    row
    a    1.0  0.5  0.3
    b    0.5  1.0  0.4
    c    0.3  0.4  1.0
    

    【讨论】:

      猜你喜欢
      • 2019-08-25
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多