python - 如何在 MultiIndex Groupby 中高效地执行乘法
问题描述
我正在尝试使用我的两个二级索引来计算第三个索引。但是,我找不到一种惯用的方法来做到这一点。
如何从其他两个二级指标计算一个二级指标?每个组都有相同的二级指标。
我的代码
import numpy as np
import pandas as pd
# Create index
tickers = ['A', 'B', 'C']
line_items = ['sales', 'ebitda_margin', 'ebitda', 'other_field']
index = pd.MultiIndex.from_product([tickers, line_items], names=['ticker', 'line_item'])
df = pd.DataFrame([100, 0.3, np.nan, 7, 200, 0.2, np.nan, 8, 300, 0.1, np.nan, 9],
index=index,
columns=[0])
# Let's assume 10% sales growth for all companies
# This is included to show that I am doing this calculation for multiple years (columns)
df[1] = df[0]
df.loc[pd.IndexSlice[:, 'sales'], 1] *= 1.1
这将产生以下数据框:
0 1
ticker line_item
A sales 100.0 110.0
ebitda_margin 0.3 0.3
ebitda NaN NaN
other_field 7.0 7.0
B sales 200.0 220.0
ebitda_margin 0.2 0.2
ebitda NaN NaN
other_field 8.0 8.0
C sales 300.0 330.0
ebitda_margin 0.1 0.1
ebitda NaN NaN
other_field 9.0 9.0
我有的
请注意,我知道我需要对索引进行一些工作才能使以下内容正常工作,但如果存在一种更好的方法而不是使用此代码,我宁愿找到更好的方法。
df.apply(lambda x: x.loc[pd.IndexSlice[:, 'sales']] * x.loc[pd.IndexSlice[:, 'ebitda_margin']])
有一个更好的方法吗?
解决方案
感谢@piRSquared 帮助我解决这个问题。以下为我做了:
piR 评论:
关键是将行项目放入列中以使数学更容易。如果数据框是面向演示的并且很小,那么 / / 可以更快地stack
/ unstack
/pivot
以便更方便地进行计算,然后stack
/ unstack
/pivot
返回。
df_restack = df.stack().unstack('line_item')
df_restack['ebitda'] = df_restack['sales'] * df_restack['ebitda_margin']
df = df_restack.stack().unstack(1)
这将产生以下数据框:
0 1
ticker line_item
A ebitda 30.0 33.0
ebitda_margin 0.3 0.3
other_field 7.0 7.0
sales 100.0 110.0
B ebitda 40.0 44.0
ebitda_margin 0.2 0.2
other_field 8.0 8.0
sales 200.0 220.0
C ebitda 30.0 33.0
ebitda_margin 0.1 0.1
other_field 9.0 9.0
sales 300.0 330.0
我会注意到,当数据框较大时,Quang 和 Andrej 的答案要快得多,所以我选择了 Quang 的答案,因为他首先回答。
推荐阅读
- sql - 多个表的反透视表
- git - x 在 master 后面提交,如何在分支上不合并 master
- typescript - 如何按字段扩展泛型类型?
- javascript - 使用 jQuery 将内容复制到文本框中
- javascript - JS计算后数字中的逗号
- azure - 恢复 velero 备份导致“缺少客户端令牌”
- python - 在函数中,如何将值分配给集合?
- c# - asp.net如何在Web表单中调用Console Application函数
- visual-studio - 在 Visual Studio 中更新 Nuget 包
- sql - 使用最大值 SQL 更新组中的所有行