Pandas dataframe.dot分割方法

时间:2015-01-29 11:24:34

标签: python matrix pandas

我试图划分两个不同长度的系列来返回它们的矩阵乘积数据帧。

我可以使用点法(from this answer)将它们相乘:

# Create series
average_read_intervals = pd.Series([10,20,30,40],
                                   index=['a','b','c','d'])
region_lengths = pd.Series([100,200,300,400,500,1000],
                           index=['z','y','x','w','v','u'])

# Convert to dataframes
R = pd.DataFrame(region_lengths)
A = pd.DataFrame(average_read_intervals)

# Dot multiplication
R.dot(A.T)
       a      b      c      d
z   1000   2000   3000   4000
y   2000   4000   6000   8000
x   3000   6000   9000  12000
w   4000   8000  12000  16000
v   5000  10000  15000  20000
u  10000  20000  30000  40000

我已经尝试过div方法,但这只是用NaN填充数据帧:

In [17]: R.div(A.T)
Out[17]: 
    0   a   b   c   d
0 NaN NaN NaN NaN NaN
u NaN NaN NaN NaN NaN
v NaN NaN NaN NaN NaN
w NaN NaN NaN NaN NaN
x NaN NaN NaN NaN NaN
y NaN NaN NaN NaN NaN
z NaN NaN NaN NaN NaN

同样,标准除法运算符也返回相同的结果:

In [18]: R / A.T
Out[1]: 
    0   a   b   c   d
0 NaN NaN NaN NaN NaN
u NaN NaN NaN NaN NaN
v NaN NaN NaN NaN NaN
w NaN NaN NaN NaN NaN
x NaN NaN NaN NaN NaN
y NaN NaN NaN NaN NaN
z NaN NaN NaN NaN NaN

所以我对我的问题的正确解决方案感到有点难过。

感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

要进行元素分割操作,您可以将每个数据帧的值分开,如下所示:

matrix_div = pd.DataFrame(R.values/A.T.values, index=R.index, columns=A.index)

产生所需的

矩阵
     a   b          c     d
z   10   5   3.333333   2.5
y   20  10   6.666667   5.0
x   30  15  10.000000   7.5
w   40  20  13.333333  10.0
v   50  25  16.666667  12.5
u  100  50  33.333333  25.0

答案 1 :(得分:0)

我不相信你可以在熊猫中,或者至少不是那样的。 div是一个元素操作,类似于mul,不是像dot这样的矩阵操作(尝试A.mul(A)或等效A * A)。*

只有当所讨论的矩阵为nonsingular时才能进行矩阵除法(乘以逆):A当然不是正方形。{1}}当然不是正方形。

Numpy具有compute the inverse of a matrix的功能,如果你的矩阵形状不同,你可以使用它。

那就是说,在你的情况下,你基本上想要在average_read_intervals的一些当前不存在的列上广播R,你可以通过改变R的形状来改造它列len(average_read_intervals)次。

# Make R into a 6 by 4 matrix with the correct column headings.
R = R.join([R.rename(columns={0: col}) for col in average_read_intervals.index]).ix[:, 1:]
R
      a     b     c     d
z   100   100   100   100
y   200   200   200   200
x   300   300   300   300
w   400   400   400   400
v   500   500   500   500
u  1000  1000  1000  1000


# Divide by Series (broadcast over D)
R / average_read_intervals

     a   b          c     d
z   10   5   3.333333   2.5
y   20  10   6.666667   5.0
x   30  15  10.000000   7.5
w   40  20  13.333333  10.0
v   50  25  16.666667  12.5
u  100  50  33.333333  25.0

但几乎肯定有更好的方法可以做到这一点。 (希望有人会加入:)

*这并不总是正确的,因为它们将broadcast取决于操作数'形状。