Python 如何使用Pandas级数和numpy数组进行矩阵乘法,并始终返回一个级数?

Python 如何使用Pandas级数和numpy数组进行矩阵乘法,并始终返回一个级数?,python,pandas,numpy,matrix-multiplication,series,Python,Pandas,Numpy,Matrix Multiplication,Series,当您将熊猫系列作为其参数之一传递时,我注意到不同Numpy版本之间存在不一致 在具有Numpy版本1.16.4的Python 3.6中 >>> import numpy as np >>> import pandas as pd >>> a = np.array(range(9)).reshape((3, 3)) >>> b = np.array([2]*3) >>> np.matmul(b, a)

当您将熊猫系列作为其参数之一传递时,我注意到不同Numpy版本之间存在不一致

在具有Numpy版本1.16.4的Python 3.6中

>>> import numpy as np
>>> import pandas as pd
>>> a = np.array(range(9)).reshape((3, 3))
>>> b = np.array([2]*3)
>>> np.matmul(b, a)                                                                                        
array([18, 24, 30])
>>> b2 = pd.Series(b)
>>> np.matmul(b2, a)
0    18
1    24
2    30
dtype: int64
(返回一个序列)

在Python 3.7和Numpy 1.15.4中

>>> a = np.array(range(9)).reshape((3, 3))
>>> b = np.array([2]*3)
>>> np.matmul(b, a)                                                                                        
array([18, 24, 30])
>>> b2 = pd.Series(b)
>>> np.matmul(b2, a)
array([18, 24, 30])
(返回一个数组)

pd.Series
传递给
matmul
是否错误?我一直认为熊猫和numpy对象可以互换(只要形状匹配)

可能的解决方案(有什么区别?):

(最终我希望返回结果作为
pd.Series

基于文档

标量、级数或numpy.ndarray返回级数的点积 而其他如果其他是一个系列,则该系列的点积为 序列和其他行(如果其他行是数据帧或 numpy.ndarray位于序列和numpy数组的每列之间

环境

pd.__version__
Out[667]: '0.25.0'
np.__version__
Out[668]: '1.16.4'
因此,使用
numpy
ndarray

我建议你检查一下时间

%timeit pd.Series(b2.dot(a), index=b2.index)
10000 loops, best of 3: 74 µs per loop
%timeit pd.Series(np.matmul(b2, a), index=b2.index)
10000 loops, best of 3: 113 µs per loop
%timeit pd.Series(np.matmul(b2.values, a), index=b2.index)
10000 loops, best of 3: 63.8 µs per loop

他们看起来和我很像。他们的信条2是“显式优于隐式”。如果您希望始终返回一个系列,那么最好显式地使用对
pd.series()
的调用来消除任何歧义,或者您发现的版本或环境之间的更改。出于同样的原因,我会(在所有条件相同的情况下)选择第三个选项,因为它只显式地将值和强制转换传递给系列(尽管在pandas 0.24中,它更倾向于
b2.to_numpy()
),根据
numpy
发行说明,
matmul
现在是
ufunc
,并接受对象数据类型数组。早期版本可能会执行
np.asarray(b2)
并执行纯
numpy
计算。这些更改中的一个或两个将在较新的代码中保留
b2
类型/类别。
b2
将其
\u值存储为
ndarray
,但它不是
ndarray
的子类。查看
b2.dot
的代码,了解pandas处理混合类型计算的方法。在我的numpy版本中,
b2.\uuuu matmul\uuuuu(其他)
(@operator)将操作委托给
self.dot(其他)
。由于
Series
是1d(和数据帧2d),使用
matmul
dot
没有任何真正的优势。
matmul
增加的一个重要功能是能够批量执行
dot
(即使用3d阵列)。谢谢。我检查了时间安排,发现它们变化很大<代码>np.matmul(b,a)
采用207205149µs(对于1000x1000阵列)和
pd.系列(b.dot(a),index=b.index)
采用170237185µs。不清楚哪个更快。
%timeit pd.Series(b2.dot(a), index=b2.index)
10000 loops, best of 3: 74 µs per loop
%timeit pd.Series(np.matmul(b2, a), index=b2.index)
10000 loops, best of 3: 113 µs per loop
%timeit pd.Series(np.matmul(b2.values, a), index=b2.index)
10000 loops, best of 3: 63.8 µs per loop