有没有办法计算交叉表数据框与熊猫中另一个数据框之间的比率?

Posted

技术标签:

【中文标题】有没有办法计算交叉表数据框与熊猫中另一个数据框之间的比率?【英文标题】:Is there a way to calculate ratio between a crosstab dataframe with another dataframe in pandas? 【发布时间】:2022-01-07 14:59:52 【问题描述】:

总结 - 最终目标是根据 Pandas 中交叉表函数的输出与共享索引处的另一个数据框计算百分比。

我尝试过的 - 尝试将原始交叉表数据框拆分为分子和 div 另一个数据框,但它似乎并没有那样工作,因为结果都是 nan

代码

import pandas as pd
import numpy as np 

df1 = pd.DataFrame("Vntg": ["2020-01","2020-02","2020-03"],"Funded":[1000,2000,4000]) # This is the df we want to use as denominator
df2 = pd.DataFrame("Vntg": ["2020-01","2020-01","2020-01","2020-02","2020-02","2020-03"],
                    "Funded":[1000,1000,1000,2000,2000,4000],
                    "Payment":[10,20,20,30,15,30],
                    "Timing":[0,1,2,0,1,0])
ct_df = pd.crosstab(df2["Vntg"], df2["Timing"], values=df2["Payment"], aggfunc="sum", margins=False)
ct_df = ct_df.cumsum(axis=1) # This is the crosstab df we want to use as numerator on a cumulative basis

cumsum 开始累积付款,有没有办法将df1 中的资金金额转换/替换为百分比?在此先感谢并感谢所有帮助。

我还查看了下面的帖子,但它似乎没有解决我的问题: Customized normalization of pd.crosstab()

编辑:

所以我认为有些人对这个问题感到困惑。澄清一下,最终结果将是在时间 0 时从 df2 中取出 10,然后除以资助金额,即 2020-01 年份从 df1 中取出 1000。对于随后在 1 的时间,它只是来自df2 的 (10+30),并为同一年份从df1 分配了相同的资金数额,因为它本质上没有改变。结果将由其他年份的相同逻辑填充。

【问题讨论】:

嗨 limasuma - 我对两个数据框中各个列的含义有些困惑,尤其是 df2 中的“付款”和“时间”。当您说“以百分比形式将df1 中的资金金额转换/替换为美元价值”时,将列除以其总数是否合适? @DaveB 是的,这是我最初的想法,只需将资金列划分为df1,但它似乎并没有解决我的问题,因为它返回所有nan 【参考方案1】:

下面的方法不使用crosstab,但应该给出相同的答案(IIUC):

(
    df2.sort_values(["Vntg", "Timing"])
    .assign(cum_paymt=lambda df: df.groupby("Timing")["Payment"].transform("cumsum"))
    .assign(cum_share=lambda df: df["cum_paymt"] / df["Funded"])
    .pivot(index="Vntg", columns="Timing", values="cum_share")
)

【讨论】:

感谢您的回答。我可以看到它是如何工作的并且非常接近。澄清一下,最终结果将是时间 0,2020-01 年份的资助金额为 10/1000,时间 1 的资助金额为 (10+30)/1000。该资助金额不会改变,它必须来自df1 因为在 df2 中的资助由于重复而膨胀。 嗯,我不确定我是否理解正确。 “资助”列不受重复项的影响,对吧? df2 中的“funded”列确实如此,因为它会根据年份从df1 简单匹配。例如,如果我们查看 df2,则 2020-01 的资助是 1000 而不是 3000。我还做了一些修改,如果有意义,请告诉我。【参考方案2】:

如果你以dataframe的形式给出预期的输出,对大家来说会更容易:

>>> ct_df.cumsum(axis=1).div(df1.set_index('Vntg')['Funded'], axis=0).mul(100)
Timing      0     1    2
Vntg                    
2020-01  1.00  3.00  5.0
2020-02  1.50  2.25  NaN
2020-03  0.75   NaN  NaN

【讨论】:

以上是关于有没有办法计算交叉表数据框与熊猫中另一个数据框之间的比率?的主要内容,如果未能解决你的问题,请参考以下文章

Python将包含科学值和浮点值的熊猫数据框与浮点数相乘

从日期时间范围创建熊猫数据框[重复]

熊猫两个数据框交叉连接[重复]

如何计算熊猫数据框中组的每对行之间的函数

有没有办法在熊猫数据框中运行 postgresql 查询?

将数据框与其他数据框合并并根据特定条件计算分组百分比