使用与ndarray相关的DataFrame.mul时出错

时间:2016-04-13 19:29:37

标签: numpy pandas error-handling dataframe

我从这篇文章中引用Get dot-product of dataframe with vector, and return dataframe, in Pandas来使用DataFrame.mul。

我的问题代码是这个

df.mul(weight)

其中weight是具有形状(17L,1L)的'numpy.ndarray'的数据类型,打印结果是

[[  2.37005330e-07]
 [  2.80515078e-07]
 [  2.80267682e-07]
 [  2.79124521e-07]
 [  2.01799847e-07]
 [  2.71495529e-07]
 [  2.81640566e-07]
 [  2.30099310e-07]
 [  1.95221059e-07]
 [  2.10244387e-07]
 [  2.82483251e-07]
 [  2.29050342e-07]
 [  9.99996381e-01]
 [  8.95340469e-08]
 [  3.90767576e-08]
 [  2.31231511e-07]
 [  2.79852240e-07]]

其中df是形状为[20208行×17列]的数据框对象,打印结果如下:

                     12&88    17&123 ....
modified datetime                        
2015-09-07 09:19:00  1.000000  1.000000  ....
2015-09-07 09:30:00  1.000000  1.000000  ....
2015-09-07 09:31:00  1.000000  0.974714  ....
2015-09-07 09:32:00  1.000000  0.978203  ....
2015-09-07 09:33:00  1.000000  0.978203  ....
2015-09-07 09:34:00  1.000000  0.990576  ....
....

但是当我执行df.mul(weight)时,它会发生

ValueError: Shape of passed values is (1, 17), indices imply (17, 20208)

我尝试了一个更简单的数组形状(17L,),使用df.mul.so我没有问题。我想知道它是否应该将重量改为ndarray到数组,但对我来说很难。如何改变OR会有更好的想法来解决这个问题吗?非常感谢你的帮助!

这是我的原始代码

   weight, means, stds = optimal_portfolio(result_framea.transpose())

   c , b= test.pairs_trade(load_path, sNo_list[0])
   result_frame = pd.DataFrame(index = c.index)
   for i, sNo in enumerate(sNo_list):
        c,b = test.pairs_trade(load_path, sNo)
        result_frame[sNo[0]+'&'+sNo[1]] = c['returns']
   df=result_frame.fillna(method='pad')

一切都很好,直到df.mul(体重)之后的那一刻。再次,谢谢!

1 个答案:

答案 0 :(得分:0)

来自help(pd.DataFrame.mul)

  

mul(self, other, axis='columns', level=None, fill_value=None)未绑定的pandas.core.frame.DataFrame方法

     

dataframeother的乘法,逐元素(二元运算符mul)。

     

等同于dataframe * other,但支持替换fill_value       其中一个输入中缺少数据。

这表明在最简单的情况下df.mul只会对相应的数组执行numpy式的乘法运算。因此,您尝试将形状(20208,17)的数组与形状(17,1)之一相乘。这不起作用。

array broadcasting在numpy中的工作方式是具有某些奇异维度的数组可以通过numpy自动扩展,以便在算术运算中将它们与其他更大的数组相匹配。问题在于,如果其中一个数组的维数较少,则假定前导单例维度。

因此,例如,可以将以下数组形状相乘或添加/分割/等等,而不会出现问题:

  • (1,17)(20208,17)因为非单身尺寸匹配
  • (17,)(20208,17),因为第一个与(1,17)隐式兼容(假设前导单身尺寸)
  • (5,1,17)and(1,20208,17)(or just(20208,17)`)

以下内容不能一起播放:

  • (1,16)(20208,17),因为尺寸不匹配
  • (16,) and(20208,17)because the mismatch is there even after implicitly expanding the first one to shape(1,16)`
  • (17,1)(20208,17)目前显而易见的原因

问题是pandas显示了您在问题中引用的神秘错误消息:

  

ValueError:传递值的形状为(1,17),指数暗示(17,1008)

在numpy中看起来像这样(试试np.random.rand(17,1)*np.random.rand(20208,17)):

  

ValueError:操作数无法与形状(17,1)(20208,17)一起广播

后一个错误非常清楚,可能会让你头疼不已。

解决方案很简单:reshape您的权重数组从形状(17,1)(二维数组中的列向量)到形状(17,)(一维数组)。这可以使用更大的阵列进行广播。要执行此操作,只需使用维度参数reshape调用-1,告诉numpy为您确定1d数组的长度:

df.mul(weight.reshape(-1))

请注意,resut与shape中的数据相同df,但每列将与weight中的相应元素相乘。