将 MultiIndex Pandas 数据帧乘以来自另一个数据帧的多个标量

Posted

技术标签:

【中文标题】将 MultiIndex Pandas 数据帧乘以来自另一个数据帧的多个标量【英文标题】:Multiply MultiIndex Pandas Dataframe by multiple scalars from another dataframe 【发布时间】:2019-06-29 13:48:02 【问题描述】:

如何将MultiIndex 数据帧中的列与多个标量(来自另一个数据帧)相乘?

对于普通数据帧,它是fairly straightforward,但当它到达 MultiIndex 数据帧时我会感到困惑。有什么建议吗?

虚拟数据:

import pandas as pd
import numpy as np

def mklbl(prefix, n):
    return ["%s%s" % (prefix, i) for i in range(n)]

miindex = pd.MultiIndex.from_product([mklbl('C', 4), mklbl('D', 2)])
micolumns = pd.MultiIndex.from_tuples([('Baseline', 'Electricity'), ('Baseline', 'Gas'), ('Consumption', 'Electricity'), ('Consumption', 'Gas')])
df = pd.DataFrame(np.arange(len(miindex) * len(micolumns))
                        .reshape((len(miindex), len(micolumns))),
                         index=miindex,
                  columns= micolumns)

cost = pd.DataFrame([['Electricity', 0.12],['Gas', 0.03]], columns=['fuel__name', 'cost_per_unit'])

预期输出是虚拟数据乘以 ElectricityGas 对应的 cost_per_unit,(即能源使用成本)

【问题讨论】:

【参考方案1】:

将第一级的列映射到值并相乘:

df_res = df*df.columns.get_level_values(1).map(cost.set_index('fuel__name').cost_per_unit)
print(df_res)

         Baseline       Consumption      
      Electricity   Gas Electricity   Gas
C0 D0        0.00  0.03        0.24  0.09
   D1        0.48  0.15        0.72  0.21
C1 D0        0.96  0.27        1.20  0.33
   D1        1.44  0.39        1.68  0.45
C2 D0        1.92  0.51        2.16  0.57
   D1        2.40  0.63        2.64  0.69
C3 D0        2.88  0.75        3.12  0.81
   D1        3.36  0.87        3.60  0.93

如果您只需要乘以特定的子集,那么您可以用各种方法对MultiIndex 进行切片,并仅对子集执行操作。

import pandas as pd
df.loc[:, df.columns.get_level_values(1) == 'Electricity']

         Baseline Consumption
      Electricity Electricity
C0 D0           0           2
   D1           4           6
C1 D0           8          10
...

使用pd.IndexSlice 可能更简洁易读

idx = pd.IndexSlice
df.loc[:, idx[:, 'Electricity']]

         Baseline Consumption
      Electricity Electricity
C0 D0           0           2
   D1           4           6
C1 D0           8          10
...

【讨论】:

这太棒了!太感谢了。 Pandas 非常灵活,但同时它的众多方法也相当棘手。

以上是关于将 MultiIndex Pandas 数据帧乘以来自另一个数据帧的多个标量的主要内容,如果未能解决你的问题,请参考以下文章

将多个键上的 pandas 数据帧映射为列或 multiIndex

MultiIndex Pandas

pandas multiindex将标签添加到索引级别

如何更新 MultiIndex pandas DataFrame 的子集

Python Pandas Multiindex Slicing/Indexing 获取重复数据

Pandas 高效的 Multiindex 获取和设置