【问题标题】:Multiply Python Pandas dataframes together to get product of values in column将 Python Pandas 数据帧相乘以获得列中值的乘积
【发布时间】:2018-04-12 13:33:16
【问题描述】:

我需要帮助创建一个 Python 函数来实现以下目标:

1) 将 3 个 Pandas 数据帧作为输入(包含一个索引列,以及第二列中的相关整数或浮点值)。这些定义如下:

import pandas as pd

df1=pd.DataFrame([['placementA',2],['placementB',4]],columns=
['placement','value'])
df1.set_index('placement',inplace=True)

df2=pd.DataFrame([['strategyA',1],['strategyB',5],['strategyC',6]],columns=
['strategy','value'])
df2.set_index('strategy',inplace=True)

df3=pd.DataFrame([['categoryA',1.5],['categoryB',2.5]],columns=
['category','value'])
df3.set_index('category',inplace=True)

2) 使用这三个数据框,创建一个新的数据框 ('df4'),它将前 3 列中 3 个索引的所有可能组合组织起来;

3) 在第 4 列中,附加三个源数据帧中所有相关“值”的数学乘积。 因此,该函数的 DataFrame 输出应如下所示:https://ibb.co/cypEY6

非常感谢您的帮助。

科林

【问题讨论】:

    标签: python pandas recursion dataframe iteration


    【解决方案1】:

    使用所有索引和列的product并通过构造函数创建DataFrame,对于多个所有列使用prod

    from  itertools import product
    
    names = ['placement','strategy','category']
    mux = pd.MultiIndex.from_product([df1.index, df2.index, df3.index], names=names)
    df = (pd.DataFrame(list(product(df1['value'], df2['value'], df3['value'])), index=mux)
           .prod(1).reset_index(name='mult'))
    print (df)
         placement   strategy   category  mult
    0   placementA  strategyA  categoryA   3.0
    1   placementA  strategyA  categoryB   5.0
    2   placementA  strategyB  categoryA  15.0
    3   placementA  strategyB  categoryB  25.0
    4   placementA  strategyC  categoryA  18.0
    5   placementA  strategyC  categoryB  30.0
    6   placementB  strategyA  categoryA   6.0
    7   placementB  strategyA  categoryB  10.0
    8   placementB  strategyB  categoryA  30.0
    9   placementB  strategyB  categoryB  50.0
    10  placementB  strategyC  categoryA  36.0
    11  placementB  strategyC  categoryB  60.0
    

    替代方案是 multiple 列表理解的所有值:

    import operator
    import functools
    from  itertools import product
    
    names = ['placement','strategy','category']
    a = list(product(df1.index, df2.index, df3.index))
    
    b = product(df1['value'], df2['value'], df3['value'])
    data = [functools.reduce(operator.mul, x, 1) for x in b]
    
    df = pd.DataFrame(a, columns=names).assign(mult=data)
    print (df)
         placement   strategy   category  mult
    0   placementA  strategyA  categoryA   3.0
    1   placementA  strategyA  categoryB   5.0
    2   placementA  strategyB  categoryA  15.0
    3   placementA  strategyB  categoryB  25.0
    4   placementA  strategyC  categoryA  18.0
    5   placementA  strategyC  categoryB  30.0
    6   placementB  strategyA  categoryA   6.0
    7   placementB  strategyA  categoryB  10.0
    8   placementB  strategyB  categoryA  30.0
    9   placementB  strategyB  categoryB  50.0
    10  placementB  strategyC  categoryA  36.0
    11  placementB  strategyC  categoryB  60.0
    

    具有DataFrames 列表的动态解决方案,只需要在每个列中使用相同的列名value

    dfs = [df1, df2, df3]
    
    names = ['placement','strategy','category']
    a = list(product(*[x.index for x in dfs]))
    b = list(product(*[x['value'] for x in dfs]))
    data = pd.DataFrame(b).product(1)
    
    df = pd.DataFrame(a, columns=names).assign(mult=data)
    print (df)
         placement   strategy   category  mult
    0   placementA  strategyA  categoryA   3.0
    1   placementA  strategyA  categoryB   5.0
    2   placementA  strategyB  categoryA  15.0
    3   placementA  strategyB  categoryB  25.0
    4   placementA  strategyC  categoryA  18.0
    5   placementA  strategyC  categoryB  30.0
    6   placementB  strategyA  categoryA   6.0
    7   placementB  strategyA  categoryB  10.0
    8   placementB  strategyB  categoryA  30.0
    9   placementB  strategyB  categoryB  50.0
    10  placementB  strategyC  categoryA  36.0
    11  placementB  strategyC  categoryB  60.0
    

    【讨论】:

    • @Bharath 猜测 itertools
    • 最好确保 itertoolspd.MultiIndex 产生相同的产品,否则您匹配的值有误。
    • Sir multi index from product 真的很不错。 Op 在输出中添加了 C 类,但没有提出问题。
    • 感谢 Jezrael - 我注意到这与我的预期输出不完全匹配。看起来输出组合中缺少我的“C 类”。我想这是一个简单的改变?另外,我想我不妨提一下,我希望将此解决方案扩展到可变数量的输入数据帧(在此示例中它不会总是 3)。
    • @ColinBlyth 这是一个非常好的解决方案,现在您可以投票了,所以请投票并感谢回答者。
    猜你喜欢
    • 2021-09-30
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2013-02-17
    相关资源
    最近更新 更多