Python 2个数据帧的元素相乘

Python 2个数据帧的元素相乘,python,pandas,dataframe,Python,Pandas,Dataframe,有两个数据帧的形状(6,4)和(6,2)。需要执行2个数据帧的元素相乘 >>> import pandas as pd >>> df1 = pd.DataFrame({'col1' : [1,2,6,8,-1,3], 'col2' : [1,2,6,8,-1,3], 'col3' : [1,2,6,8,-1,3], 'col4' : [1,2,6,8,-1,3]}) >>> df1 col1 col2 col3 col4 0

有两个数据帧的形状(6,4)和(6,2)。需要执行2个数据帧的元素相乘

>>> import pandas as pd
>>> df1 = pd.DataFrame({'col1' : [1,2,6,8,-1,3], 'col2' : [1,2,6,8,-1,3], 'col3' : [1,2,6,8,-1,3], 'col4' : [1,2,6,8,-1,3]})
>>> df1
   col1  col2  col3  col4
0     1     1     1     1
1     2     2     2     2
2     6     6     6     6
3     8     8     8     8
4    -1    -1    -1    -1
5     3     3     3     3
>>>
>>> df2 = pd.DataFrame({'col1' : [9,8,7,1,1,1], 'col2' : [11,12,16,2,2,1]})
>>> df2
   col1  col2
0     9    11
1     8    12
2     7    16
3     1     2
4     1     2
5     1     1
预期产出:

0     9     9       9       9       
1     16    16      16      16      
2     42    42      42      42      
3     8     8       8       8       
4     -1    -1      -1      -1      
5     3     3       3       3       

0   11      11      11      11
1   24      24      24      24
2   96      96      96      96
3   16      16      16      16
4   -2      -2      -2      -2
5   3       3       3       3
方法1:

a = np.array(df1.values)
b = np.array(df2.values)
尝试以下方法

c = a * b
错误:#ValueError:操作数无法与形状(6,4)和(6,2)一起广播

方法2:

已将1个数据帧转换为系列

df_temp=df1[df1.columns.values['a']]
func = lambda x: np.asarray(x) * np.asarray(df2[df2.columns.values[0]])

df_temp.apply(func)
输出: 无法获得元素级输出

方法3:

将DF转换为列表并将列表相乘:

df11=list(df1.values.flatten())
df22=list(df2.values.flatten())

但是,结果列表不是二维的;。它是一维的。

如果您可以以numpy数组的形式获取输出,那么这种方法是有效的

map(lambda col: df2[col].values.reshape(-1, 1) * df1.values, df2)
编辑:这是一个更清晰的输出,如下所示:

map(lambda col: df1.mul(df2[col], axis=0), df2)
您应该使用.multiply():

这将返回:

   col1  col2  col3  col4
0     9     9     9     9
1    16    16    16    16
2    42    42    42    42
3     8     8     8     8
4    -1    -1    -1    -1
5     3     3     3     3

   col1  col2  col3  col4
0    11    11    11    11
1    24    24    24    24
2    96    96    96    96
3    16    16    16    16
4    -2    -2    -2    -2
5     3     3     3     3

您应该能够通过以下方式创建所需的结果:

>>> [df1.apply(lambda x: x*y) for _, y in df2.iteritems()]
[   col1  col2  col3  col4
 0     9     9     9     9
 1    16    16    16    16
 2    42    42    42    42
 3     8     8     8     8
 4    -1    -1    -1    -1
 5     3     3     3     3,
    col1  col2  col3  col4
 0    11    11    11    11
 1    24    24    24    24
 2    96    96    96    96
 3    16    16    16    16
 4    -2    -2    -2    -2
 5     3     3     3     3]
或者使用@Alex的乘法方法,也可以这样做。您还可以将它们合并到单个多索引数据帧中:

>>> pd.concat((df1.mul(y, axis=0) for _, y in df2.iteritems()), axis=1, keys=df2)
  col1                col2               
  col1 col2 col3 col4 col1 col2 col3 col4
0    9    9    9    9   11   11   11   11
1   16   16   16   16   24   24   24   24
2   42   42   42   42   96   96   96   96
3    8    8    8    8   16   16   16   16
4   -1   -1   -1   -1   -2   -2   -2   -2
5    3    3    3    3    3    3    3    3

感谢@Alex提供详细信息


(df2.iteritems()中的uy的df1.mul(y,axis=0)

这里有一个指向.multiply()文档的链接:谢谢@sjosund。。我尝试过这种方法。这是一个可伸缩性问题。。一旦我将数据帧形状增加到(35000100)和(35000,2);乘法运算速度变慢了。。。这个过程持续了20分钟。。然后我杀了它。谢谢@Alex提供的详细信息。。请详细说明语法:df2.iteritems()中的uy,y的df1.mul(y,axis=0),axis=1,keys=df2语法如下。pandas较新版本中的mul()或.multiply()将一个系列、数据帧或常量作为其唯一必需的参数。将轴设置为零意味着您将在索引轴上对齐元素后对其进行乘法。最后,for循环使用iteritems()一次选择df2数据帧的每一列。当像这样取出时,这些列成为熊猫系列,并且每个列依次传递给df1.mul(y,axis=0)命令。这个列表理解在我上面的回答中显示为for循环。
df1.mul(y,axis=0)
将df1乘以y,但使用索引(axis=0)vs列,在相乘之前有效地转置。其余的是一个生成器,它遍历df2中的每一列并将其分配给y,查找理解和生成器。
>>> pd.concat((df1.mul(y, axis=0) for _, y in df2.iteritems()), axis=1, keys=df2)
  col1                col2               
  col1 col2 col3 col4 col1 col2 col3 col4
0    9    9    9    9   11   11   11   11
1   16   16   16   16   24   24   24   24
2   42   42   42   42   96   96   96   96
3    8    8    8    8   16   16   16   16
4   -1   -1   -1   -1   -2   -2   -2   -2
5    3    3    3    3    3    3    3    3