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

时间:2018-06-11 15:09:38

标签: python pandas dataframe

假设我在一个我想要使用的pandas数据框中有一些数据。

>>> 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值为列名,valval2为行名,其中值应按以下方式组成:

  1. 根据id构建值列的平均值,留下类似

    的内容
    id   mean-val   mean-val2
    a    11         5.5
    b    4.5        6
    
  2. 根据mean-val(例如mean-val2)计算id11 / (11+5.5) * 100 = 66.67对两个值之和的百分比,呈现

    id    perc-val   perc-val2
    a     66.67      33.33
    b     42.86      57.14
    
  3. 最终的数据框应如下所示:

    >>> 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 个答案:

答案 0 :(得分:2)

是的,有。

  1. 如果您在每列上取平均值,则不必指定列名称
  2. 您可以使用DataFrame.div(或除法运算符__div__
  3. 对您的部门进行矢量化

    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