【问题标题】:How to "multiply" dataframes with each other in Python?如何在 Python 中“相乘”数据帧?
【发布时间】:2021-04-21 10:47:40
【问题描述】:

我在 Python/pandas 中有两个数据框,如下所示:

df1 =
[[2001 年 1 月 1 日,2004 年 1 月 4 日,2007 年 12 月 12 日],
[2002 年 2 月 7 日,北美,北美],
[2012 年 4 月 8 日,2018 年 2 月 11 日,北美]]

df2 =
[[1, 3, 2],
[2, 不适用, 不适用],
[3, 1, NA]]

我想创建第三个数据框,如下所示:

df3 =
[[2001 年 1 月 1 日,2004 年 1 月 4 日,2004 年 4 月 1 日,2004 年 1 月 4 日,2007 年 12 月 12 日,2007 年 12 月 12 日],
[02/07/2002, 02/07/2002, NA, NA, NA, NA],
[04/08/2012, 04/08/2012, 04/08/2012, 02/11/2018, NA, NA]]

换句话说,第二个 df 给出了我想将第一个 df 的相应值复制到第三个的次数。由于没有更好的词,我在问题中称其为“乘法”,尽管我意识到这可能是错误的。

有人知道有效地做到这一点的方法吗?我的方法是为每一行使用循环和列表,但我猜应该有一种更有效的方式在 Python 中执行此操作。非常感谢您的帮助,再次抱歉在这里可能使用了错误的术语。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    完全vectorized solution不能由这个逻辑产生,但我们可以从list comprehensionnumpypython Inbuilt操作中获益。

    逻辑:
    1. 使用np.repeat 其中Array manipulation routines 我们将使用它沿dataframe df1 行重复,其中repeats 的参数np.repeat 函数的行将是 df2 对象的行。

    np.repeat(df1.iloc[i,:], df2_u.iloc[i,:].astype('i4'))
    

    2. 重要要注意的是repeats 参数的类型应该是int,我们将使用astype('i4'),即np.int32 数据类型在list comprehension 时转换df2 行。

    df2_u.iloc[i,:].astype('i4')
    

    3. 最后如何重复np.nan 值形式np.nan 只需将df2 更新为df2_u 其中NA 使用此操作填充0

    df2_u = df2.fillna(0)
    

    通用解决方案,这里的逻辑工作就像我们通过unequal-sizenested-listlist of lists 将导致DataFrame-Object 广播rowfill 所有未定义值np.nan 对象。

    代码:

    import pandas as pd
    import numpy as np
    
    df1 = pd.DataFrame([['01/01/2001', '01/04/2004', '12/12/2007'],
                        ['02/07/2002', np.nan, np.nan],
                        ['04/08/2012', '02/11/2018', np.nan]])
    
    df2 = pd.DataFrame([[1, 3, 2], [2, np.nan, np.nan], [3, 1, np.nan]])
    
    df1_sub = df1
    df2_sub = df2.fillna(0)
    
    df3 = pd.DataFrame([list(np.repeat(df1_sub.iloc[i,:], df2_sub.iloc[i,:].astype('i4')) )for i in range(df1_sub.shape[0])])
    print(df3)
    

    输出:

    [['01/01/2001' '01/04/2004' '01/04/2004' '01/04/2004' '12/12/2007''12/12/2007']
     ['02/07/2002' '02/07/2002' nan nan nan nan]
     ['04/08/2012' '04/08/2012' '04/08/2012' '02/11/2018' nan nan]]
    

    【讨论】:

    • 非常感谢,这似乎让我快到了我想去的地方!我仍然坚持输出(arr)。我得到一个数组作为输出,它似乎包含我想要的 df3 的每一行作为一个对象。你能告诉我如何将这个数组重铸为数据框(每行中有必要数量的 NaN,以便它填充到最大列数)?
    • @Benjamin 在这里我将解决方案更新为Method-1,如果您有任何问题,请告诉我
    • 仅将2 替换为0 将导致更正
    • 太棒了,这就是我要找的!非常感谢! PS:如果您有改写问题的提示,以便其他有相同/相关问题的人可以找到它,我很乐意这样做。再次感谢您的帮助!
    猜你喜欢
    • 2018-04-12
    • 2018-07-12
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多