在多索引中划分行

Dividing rows within a multiindex

晚上好所有碰巧发现这个的人post!

在多指数中将股票净收入除以其总收入时,我遇到了一个小问题。

代码如下:

import yahoo_fin.stock_info as si
import pandas as pd

company = ['AMZN', 'FB']

inc = {}
for ticker in company:
    inc[ticker] = si.get_income_statement(ticker)
df = pd.concat(inc)

pM = df.loc[(slice(None), ['netIncome', 'totalRevenue']), :]
pM

现在,所有这些代码都应该 return 我公司代码,以及前 4 年的净收入和总收入。这正是我所需要的,到目前为止一切都很好...

然后我想将指数中的每家公司(代码)除以 netIncome 除以 totalRevenue(同一家公司的),然后乘以 100 得到利润率百分比...

如果我使用下面的代码return行中有大量 NaN...

test = pM.loc[(slice(None), 'netIncome'), :] / pM.loc[(slice(None), 'totalRevenue'), :] * 100
test

但是如果我像这样手动输入公司代码:

pM.loc[('AMZN', 'netIncome'), :] / pM.loc[('AMZN', 'totalRevenue'), :] * 100

    endDate
2019-12-31    4.13087
2018-12-31    4.32527
2017-12-31    1.70522
2016-12-31    1.74355
dtype: object

它 return 是我正在寻找的,与那家公司......但显然,如果我正在砍伐和改变或在 'company' 列表中有多个股票代码,那么你可以看会不会有点啰嗦...

这些都是我问自己的问题,找不到答案,所以我的最终解决方案就在这个论坛上!

我真的不想用我的问题打扰任何人,但我不知道还能做什么:(

提前谢谢你,希望我写的一切都清楚,有任何问题让我知道。

失败的原因是两个操作数的索引没有对齐:

>>> pM.loc[(slice(None), 'netIncome'), :]
endDate          2019-12-31   2018-12-31   2017-12-31   2016-12-31
     Breakdown                                                    
AMZN netIncome  11588000000  10073000000   3033000000   2371000000
FB   netIncome  18485000000  22112000000  15934000000  10217000000

>>> pM.loc[(slice(None), 'totalRevenue'), :]
endDate              2019-12-31    2018-12-31    2017-12-31    2016-12-31
     Breakdown                                                           
AMZN totalRevenue  280522000000  232887000000  177866000000  135987000000
FB   totalRevenue   70697000000   55838000000   40653000000   27638000000

pandas在第二帧中寻找标签(AMZN, netIncome),没有找到所以修改结果是N/A。与其他行相同。


你想要的是xs:

margin = (
    pM.xs((slice(None), 'netIncome'))
        .div(pM.xs((slice(None), 'totalRevenue')))
        .mul(100)
        .assign(Breakdown='profitMargin')
        .set_index('Breakdown', append=True)
)

pM = pM.append(margin).sort_index()

您可以看到仅向数据框添加一个指标需要多少工作。那是因为您的 pM 框架设计效率低下。试试这个:

company = ['AMZN', 'FB']

inc = {}
for ticker in company:
    inc[ticker] = si.get_income_statement(ticker).T # ← added a `.T` here
df = pd.concat(inc)

df['profitMargin'] = df['netIncome'] / df['totalRevenue'] * 100