【问题标题】:Multiply dataframes with differnet lengths regarding columns names将关于列名称的不同长度的数据帧相乘
【发布时间】:2016-05-01 14:29:26
【问题描述】:

我有两个数据框,第一个 df1 只包含一行:

   A  B  C  D  E
0  5  8  9  5  0

第二个有多行,但列数相同:

   D  C  E  A  B
0  5  0  3  3  7
1  9  3  5  2  4
2  7  6  8  8  1
3  6  7  7  8  1
4  5  9  8  9  4
5  3  0  3  5  0
6  2  3  8  1  3
7  3  3  7  0  1
8  9  9  0  4  7
9  3  2  7  2  0

在实际示例中,我有更多的列(超过 100 个)。两个数据框具有相同的列数和相同的列名,但列的顺序不同,如示例中所示。 我应该将两个数据帧相乘(matrix_like 乘法),除了我不能执行简单的df2.values * df1.values 因为列的排序方式不同,所以例如 df1 B 的第二列不能' t 在 df2 的第二列乘以,因​​为我们在 df2 的第二列找到 C 而不是 B,而列 B 是df2 中的第 5 列。

考虑到列名不是列索引,是否有简单和 Pythonic 的解决方案来乘以数据帧?

【问题讨论】:

    标签: python pandas dataframe match matrix-multiplication


    【解决方案1】:

    df1[df2.columns] 返回一个数据框,其中列按 df2 中的顺序排列:

    df1
    Out[91]: 
       A  B  C  D  E
    0  3  8  9  5  0
    
    df1[df2.columns]
    Out[92]: 
       D  C  E  A  B
    0  5  9  0  3  8
    

    所以,你只需要:

    df2.values * df1[df2.columns].values
    

    如果您在 df2 中有其他列,这将引发关键错误;即使您在 df1 中有更多列,它也只会选择 df2 的列。

    正如@MaxU 所说,由于您正在对 numpy 数组进行操作,因此为了返回您需要的数据帧结构:

    pd.DataFrame(df2.values * df1[df2.columns].values, columns = df2.columns)
    

    【讨论】:

      【解决方案2】:

      你可以使用muldf1ix转换成Serie

      print df1.ix[0]
      A    5
      B    8
      C    9
      D    5
      E    0
      Name: 0, dtype: int64
      
      print df2.mul(df1.ix[0])
          A   B   C   D  E
      0  15  56   0  25  0
      1  10  32  27  45  0
      2  40   8  54  35  0
      3  40   8  63  30  0
      4  45  32  81  25  0
      5  25   0   0  15  0
      6   5  24  27  10  0
      7   0   8  27  15  0
      8  20  56  81  45  0
      9  10   0  18  15  0
      

      如果您需要更改最终DataFrame 的顺序,请使用reindex_axis

      print df2.mul(df1.ix[0]).reindex_axis(df2.columns.tolist(), axis=1)
          D   C  E   A   B
      0  25   0  0  15  56
      1  45  27  0  10  32
      2  35  54  0  40   8
      3  30  63  0  40   8
      4  25  81  0  45  32
      5  15   0  0  25   0
      6  10  27  0   5  24
      7  15  27  0   0   8
      8  45  81  0  20  56
      9  15  18  0  10   0
      

      另一种解决方案是按reindex indexSerie 中的df2.columns 重新排序列:

      print df2.mul(df1.ix[0].reindex(df2.columns))
          D   C  E   A   B
      0  25   0  0  15  56
      1  45  27  0  10  32
      2  35  54  0  40   8
      3  30  63  0  40   8
      4  25  81  0  45  32
      5  15   0  0  25   0
      6  10  27  0   5  24
      7  15  27  0   0   8
      8  45  81  0  20  56
      9  15  18  0  10   0
      

      【讨论】:

      • 感谢您的回答,即使我将另一个标记为正确的,因为我发现它更pythonic,您的解决方案很有趣并且效果也很好,所以我很高兴地支持它!跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 2018-07-12
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-10
      相关资源
      最近更新 更多