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

使用中间计算从其他数据帧创建数据帧

  •  0
  • KorbenDose  · 技术社区  · 6 年前

    假设我在熊猫数据框中有一些要使用的数据。

    >>> df = pd.DataFrame([['a',10,5],['a',12,6],['b',4,2],['b',5,10]],
    ...                   columns=['id','val','val2']))
    

    所以数据框架看起来是这样的:

    >>> df
        id   val   val2
    0   a    10    5
    1   a    12    6
    2   b    4     2
    3   b    5     10
    

    我想要实现的是一个包含 id 列名称值和 val val2 作为行名称,其中值应按以下方式组成:

    1. 基于以下内容生成值列的平均值 身份证件 留下一些像

      id   mean-val   mean-val2
      a    11         5.5
      b    4.5        6
      
    2. 计算的百分比 mean-val mean-val2 基于两个值的和 身份证件 (例如 11 / (11+5.5) * 100 = 66.67 ),渲染

      id    perc-val   perc-val2
      a     66.67      33.33
      b     42.86      57.14
      

    最终数据帧应如下所示:

    >>> new_df
           a       b
    val    66.67   42.86
    val2   33.33   57.14
    

    我的方法

    我对熊猫很不熟悉,所以我花了一段时间才找到一个不满意的方法。

    >>> idx = ['val','val2']
    >>> lst = [df.groupby('id')[index].mean() for index in idx]
    >>> df_new = pd.DataFrame(
    ...     [[x/y*100 for x, y in zip(lst2,sum(lst))] for lst2 in lst],
    ...     index=idx, columns=df['id'].unique())
    

    这是可行的,但我不确定是否保证列或行的命名顺序正确,或者是否可能,例如, a 列已命名 b 反之亦然。

    所以我真正的问题是,是否有一种更好,更清洁,更安全,也许更有效的方法来做到这一点。

    1 回复  |  直到 6 年前
        1
  •  2
  •   cs95 abhishek58g    6 年前

    是的,有。

    1. 您可以使用 DataFrame.div __div__ )

    v = df.groupby('id').mean()
    v.T / v.sum(1) * 100          # thanks to @fuglede
    # v.div(v.sum(1), axis=0).T   # thanks to @Scott Boston
    
    id            a          b
    val   66.666667  42.857143
    val2  33.333333  57.142857