Python 多指标数列点积
我有一个包含多组数组的系列Python 多指标数列点积,python,pandas-groupby,Python,Pandas Groupby,我有一个包含多组数组的系列 import pandas as pd idx = ['a', 'b', 'c'] w = pd.Series(data=[10, 5, 20, 6, 8, 5], index=pd.MultiIndex.from_product([['foo', 'bar'], idx])) w Out[5]: foo a 10 b 5 c 20 bar a 6 b 8
import pandas as pd
idx = ['a', 'b', 'c']
w = pd.Series(data=[10, 5, 20, 6, 8, 5],
index=pd.MultiIndex.from_product([['foo', 'bar'], idx]))
w
Out[5]:
foo a 10
b 5
c 20
bar a 6
b 8
c 5
因此,foo
是一个数组,bar
是另一个数组。我想用相关矩阵乘以foo
和bar
。基本上我想计算(w*m*w)**.5
m = pd.DataFrame({idx[0]: [1.0, 0.5, 0.2],
idx[1]: [0.5, 1.0, 0.3],
idx[2]: [0.2, 0.3, 1.0]},
index=idx)
我两个都试过了
w.groupby(level=0).apply(lambda x: m.dot(x).dot(x)**.5)
及
两者都导致了
ValueError: matrices are not aligned
预期的结果应该是这样的
foo 26.739483914241877
bar 14.45683229480096
我猜这与w
有一个多索引这一事实有关。在单个数组上执行相同的操作会得到预期的结果
v = pd.Series(data=[10, 5, 20], index=idx)
m.dot(v).dot(v)**.5
Out[9]: 26.739483914241877
你有什么想法可以让它工作吗
编辑 使用一种变通方法,在函数中去掉最外层的多索引,我让它工作起来。我仍然对其他可能更清洁的解决方案持开放态度
def calc(v, m):
# Copy v and make a new index, dropping outmost index.
u = v.copy()
u.index = v.index.droplevel(0)
return m.dot(u).dot(u)**.5
w.groupby(level=0).apply(lambda x: calc(x,m))
Out[13]:
bar 14.456832
foo 26.739484
dtype: float64
使用
重塑
功能将多索引序列转换为矩阵的更简洁方法可能有助于:
q = w.values.reshape(3,2)
q
输出变为
array([[10, 5],
[20, 6],
[ 8, 5]], dtype=int64)
然而,不幸的是,我无法重现该解决方案。这里是一种简单的方法,尽管在重塑阵列时需要一些手动操作。如果你觉得这个答案很有用,我可以为你实现自动化
#首先定义要使用的简单函数
def校准点(阵列,m):
返回m.dot(数组).dot(数组)**.5
#然后,剩下的就变得微不足道了
name=w.index.droplevel(1).unique()
#注意:您需要手动设置阵列的重塑
pd.系列([计算w值中x的点(x,m)重塑(2,3)],索引=名称)
您是否尝试使用numpy库轻松进行矩阵运算?我知道numpy。出于各种原因,我更喜欢使用索引('a','b','c'),这就是为什么我想坚持使用熊猫。但是谢谢你的建议。如果你分享矩阵点运算的数学符号和预期结果,而不是熊猫,任何帮助可能会更容易。因为矩阵没有对齐。我想友好地提醒你,你可以从这个计算器模拟你的计算:如果你没有得到任何错误,我们可以很容易地理解没有算术错误,那么我们可以专注于代码。请复制页面的链接来计算:是的。这很有效。我唯一的问题是,索引不一定是经过排序的。通过将索引保持在x
(在您的列表理解中),dot
-函数自动对齐x
和m
。由于x
只是值,因此它不一定与索引上的m
对齐。我承认在最初的问题中没有提到这一点。你这是什么意思?Foo和bar是你索引它们的方式,这就是为什么第一个是Foo,另一个是bar。你需要把这个分类吗?您的预期输出表明不是这样。原则上是的。真正的索引(这是一个构造的示例)不是a、b和c,列的顺序也不是字母顺序。但是是的。排序可以解决它。你知道怎么分类吗?对我来说似乎不太难:)是的。我希望利用我提到的关于点与索引对齐等等的东西。。。但这只是吹毛求疵。你的解决方案有效。
array([[10, 5],
[20, 6],
[ 8, 5]], dtype=int64)