【问题标题】:Create dataframe from other dataframe with intermediate calculations使用中间计算从其他数据帧创建数据帧
【发布时间】:2018-11-20 21:21:56
【问题描述】:

假设我想使用 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. 根据id(例如11 / (11+5.5) * 100 = 66.67)计算mean-valmean-val2在两个值之和上的百分比,渲染

    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

我的方法

我对 pandas 非常缺乏经验,所以我花了一段时间才得到一个不满意的方法。

>>> 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,反之亦然反之亦然。

所以我的实际问题是,是否有更好、更清洁、更安全、或许更有效的方法来做到这一点。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    是的,有。

    1. 如果您对每一列取平均值,则不必指定列名
    2. 您可以使用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
    

    【讨论】:

    • 或者,稍微短一点,v.T/v.sum(1)*100
    • 不用担心。 (请注意,您的第 2 点不再那么重要了。)
    • dfm.div(dfm.sum(1), axis=0).T 我认为在这种情况下运行得更快。
    • 这就是我喜欢python的地方。谢谢大家,这帮助很大。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    相关资源
    最近更新 更多