【问题标题】:column multiplication based on a mapping基于映射的列乘法
【发布时间】:2022-01-14 17:13:23
【问题描述】:

我有以下两个数据框。第一个,将一些节点映射到区域号和该节点的最大电力负荷。

bus = pd.DataFrame(data={'Node':[101, 102, 103, 104, 105], 'Area':[1, 1, 2, 2, 3], 'Load':[10, 15, 12, 20, 25]})

这给了我们:

   Bus  Area  Load
0  101     1    10
1  102     1    15
2  103     2    12
3  104     2    20
4  105     3    25

第二个数据框显示了一段时间内(从 0 到 5 小时)每个区域的总电力负荷。列名是区域(匹配数据框bus 中的列Area

load = pd.DataFrame(data={1:[20, 18, 17, 19, 22, 25], 2:[23, 25,24, 27, 30, 32], 3:[10, 14, 19, 25, 22, 20]})

这给了我们:

    1   2   3
0  20  23  10
1  18  25  14
2  17  24  19
3  19  27  25
4  22  30  22
5  25  32  20

我想要一个数据框来显示每辆巴士在 6 小时内的电力负载。 假设:负载随时间变化的百分比与bus中显示的最大负载百分比相同;例如,101 路公交车有 10/(10+15)=0.4% 的区域 1 的电力负荷,因此,要计算其小时负荷,应将 10/(10+15) 乘以 @ 中与区域 1 对应的列987654328@.

所需的输出应为以下格式:

    101     102     103     104     105
0   8       12      8.625   14.375  10
1   7.2     10.8    9.375   15.625  14
2   6.8     10.2    9       15      19
3   7.6     11.4    10.125  16.875  25
4   8.8     13.2    11.25   18.75   22
5   10      15      12      20      20

对于第 101 列,我们有 0.4 乘以 load 的第 1 列。

非常感谢任何帮助。

【问题讨论】:

    标签: python-3.x pandas dataframe pandas-groupby


    【解决方案1】:

    您可以计算总线中的比率,转置负载,合并两者并将比率乘以负载,这里是:

    bus['area_sum'] = bus.groupby('Area')['Load'].transform('sum')
    bus['node_ratio'] = bus['Load'] / bus['area_sum']
    
    full_data = bus.merge(load.T.reset_index(), left_on='Area', right_on='index')
    
    result = pd.DataFrame([full_data['node_ratio'] * full_data[x] for x in range(6)])
    result.columns = full_data['Node'].values
    

    结果:

    101 102 103 104 105
    0 8 12 8.625 14.375 10
    1 7.2 10.8 9.375 15.625 14
    2 6.8 10.2 9 15 19
    3 7.6 11.4 10.125 16.875 25
    4 8.8 13.2 11.25 18.75 22
    5 10 15 12 20 20

    【讨论】:

      【解决方案2】:

      一种选择是将Load 除以sum,然后进行旋转,获得loadbus 的索引匹配,然后在匹配级别上相乘:

      (bus.assign(Load = bus.Load.div(bus.groupby('Area').Load.transform('sum')))
          .pivot(None, ['Area', 'Node'], 'Load')
          .reindex(load.index)
          .ffill() # get the data spread into all rows
          .bfill()
          .mul(load, level=0)
          .droplevel(0,1)
          .rename_axis(columns=None)
      ) 
          101   102     103     104   105
      0   8.0  12.0   8.625  14.375  10.0
      1   7.2  10.8   9.375  15.625  14.0
      2   6.8  10.2   9.000  15.000  19.0
      3   7.6  11.4  10.125  16.875  25.0
      4   8.8  13.2  11.250  18.750  22.0
      5  10.0  15.0  12.000  20.000  20.0
      

      【讨论】:

        猜你喜欢
        • 2022-10-06
        • 2016-05-15
        • 2018-11-06
        • 1970-01-01
        • 1970-01-01
        • 2021-04-10
        • 1970-01-01
        • 1970-01-01
        • 2021-07-09
        相关资源
        最近更新 更多