代码之家  ›  专栏  ›  技术社区  ›  Stef

数据帧中所有行之间的最大元素差异

  •  1
  • Stef  · 技术社区  · 6 年前

    给出以下数据帧:

          c1  c2  c3  c4
    code
    x      1   2   1   1
    y      3   2   2   1
    z      2   0   4   1
    

    对于此数据帧中的任何行,我希望计算此行与此数据帧的所有其他行之间的最大元素绝对差,并将其放入新的数据帧:

           x   y   z
    code
    x      0   2   3
    y      2   0   2
    z      3   2   0
    

    (当然,结果是一个主对角线为0的三角形矩阵,因此只需得到上半个或下半个三角形就足够了)。

    例如,行x和行y之间的最大元素差异为2(从c1列: abs(3 - 1) = 2 )

    到目前为止我得到的:

    df = pd.DataFrame(data={'code': ['x','y','z'], 'c1': [1, 3, 2], 'c2': [2, 2, 0], 'c3': [1,2,4], 'c4': [1,1,1]})
    df.set_index('code', inplace = True)
    
    df1 = pd.DataFrame()
    
    for row in df.iterrows():
       df1.append((df-row[1]).abs().max(1), ignore_index = True)
    

    当以交互方式运行时,这看起来已经接近我所需要的,但是新的df1之后仍然是空的:

    >>> for row in df.iterrows(): df1.append((df-row[1]).abs().max(1),ignore_index=True)
    ...
         x    y    z
    0  0.0  2.0  3.0
         x    y    z
    0  2.0  0.0  2.0
         x    y    z
    0  3.0  2.0  0.0
    >>> df1
    Empty DataFrame
    Columns: []
    Index: []
    

    问题:

    1. 如何将结果放入新的数据框中 df1 (索引x,y,…)正确吗?
    2. 这只是一个 mcve . 实际上,df大约有700行。不确定是否 iterrows 那就太好了。我觉得 apply 方法在这里很有用,但我想不出来。那么,是否还有其他类似于熊猫的惯用方法可以做到这一点而无需对行进行明确的迭代?
    2 回复  |  直到 6 年前
        1
  •  1
  •   jpp    6 年前

    您可以使用numpy并向 pd.DataFrame 构造函数。对于少数行(如数据中的行),这应该是有效的。

    A = df.values
    res = pd.DataFrame(np.abs(A - A[:, None]).max(2),
                       index=df.index, columns=df.index.values)
    
    print(res)
    
          x  y  z
    code         
    x     0  2  3
    y     2  0  2
    z     3  2  0
    
        2
  •  0
  •   heena bawa    6 年前

    如果您希望代码生成正确的输出,那么可以再次将计算出的值赋给df1。

    for row in df.iterrows():
        df1 = df1.append((df-row[1]).abs().max(1), ignore_index = True)
    
    df1.index = df.index
    print (df1)
    
         x    y    z
    X  0.0  2.0  3.0
    y  2.0  0.0  2.0
    z  3.0  2.0  0.0