我有一个包含多个 sets 个数组的系列。
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)
和
m.dot(w).dot(w)**.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
关于如何进行这项工作的任何想法?
使用一种变通方法,将multiindex的最顶层删除到一个函数中,我开始使用它。我仍然对其他也许更清洁的解决方案持开放态度。
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
答案 0 :(得分:1)
这是一种简单的方法,尽管在重塑阵列时需要一些手动操作。如果您认为此答案有用,我可以为您自动化。
# First define a simple function to be used
def calc_dot(array, m):
return m.dot(array).dot(array)**.5
# Then, the rest becomes trivial
names = w.index.droplevel(1).unique()
# Note you would need to set reshape of array manually
pd.Series([calc_dot(x, m) for x in w.values.reshape(2,3)], index = names)
答案 1 :(得分:0)
使用reshape
函数将多索引序列转换为矩阵的一种更简洁的方法可能会有所帮助:
q = w.values.reshape(3,2)
q
输出变为
array([[10, 5],
[20, 6],
[ 8, 5]], dtype=int64)
但是,不幸的是,我无法复制该解决方案。