Pandas多索引DataFrame无法用loc插入行的替代方案咨询
解决Pandas多索引DataFrame添加计算行的KeyError问题
首先,咱们先把你的原始DataFrame重现出来,方便理解场景:
import pandas as pd import numpy as np # 构建你提到的多索引DataFrame df = pd.DataFrame.from_dict({ (4.0, 'Net Sales'): { ('details', pd.Timestamp('2020-04-01 00:00:00'), 'Apr_FY21'): 1000, ('details', pd.Timestamp('2020-05-01 00:00:00'), 'May_FY21'): 1000, ('details', pd.Timestamp('2020-06-01 00:00:00'), 'Jun_FY21'): 1000 }, (5.0, 'Margin'): { ('details', pd.Timestamp('2020-04-01 00:00:00'), 'Apr_FY21'): 20, ('details', pd.Timestamp('2020-05-01 00:00:00'), 'May_FY21'): 15, ('details', pd.Timestamp('2020-06-01 00:00:00'), 'Jun_FY21'): 10 } }).T
你遇到的KeyError,核心原因是Pandas新版本(1.0+之后)收紧了.loc的索引规则,不再允许传递包含缺失标签的类列表对象来赋值新行。另外你的原代码里还有个小拼写错误((5,'Margin)')多了个闭合括号),不过咱们重点看替代方案。
下面给你几种可行的解决方法:
方案一:用pd.concat拼接新行(推荐,适配新版本)
这种方法逻辑清晰,先单独计算出Margin%的结果,给它设置好对应的多索引,再和原DataFrame拼接:
# 计算Margin%的数值:Margin除以Net Sales再乘以100 margin_pct_values = (df.loc[(5.0, 'Margin')] / df.loc[(4.0, 'Net Sales')]) * 100 # 为新行创建匹配的多索引 margin_pct_series = margin_pct_values.to_frame().T margin_pct_series.index = pd.MultiIndex.from_tuples( [(5.1, 'Margin %')], names=df.index.names ) # 拼接原DataFrame和新行 df_updated = pd.concat([df, margin_pct_series])
方案二:重置索引后添加行(更直观)
如果觉得多索引操作有点绕,可以先把索引转成普通列,添加完新行再重新设置多索引:
# 把多索引转成普通列 df_reset = df.reset_index() # 动态计算新行的数值 new_row_values = (df.loc[(5.0, 'Margin')] / df.loc[(4.0, 'Net Sales')]) * 100 # 构造新行的完整数据 new_row = pd.Series({ 'level_0': 5.1, 'level_1': 'Margin %' }).append(new_row_values) # 添加新行到重置后的DataFrame df_reset = pd.concat([df_reset, new_row.to_frame().T], ignore_index=True) # 重新设置多索引 df_updated = df_reset.set_index(['level_0', 'level_1'])
方案三:用append(仅适合Pandas 2.0以下版本)
如果你的Pandas版本还比较旧(2.0之前),可以直接用append方法,不过这个方法已经被官方弃用了,不推荐长期使用:
# 构造带多索引名称的Series margin_pct_series = pd.Series( (df.loc[(5.0, 'Margin')] / df.loc[(4.0, 'Net Sales')]) * 100, name=(5.1, 'Margin %') ) # 添加到原DataFrame df_updated = df.append(margin_pct_series)
执行完任意一种方案后,你都会得到包含(5.1, 'Margin %')行的DataFrame,对应的数值分别是2.0、1.5、1.0,完全符合你的计算逻辑。
内容的提问来源于stack exchange,提问作者Ankit Goel
相关产品推荐
相关产品推荐

