在时间序列索引的 DataFrame 的每一列上应用调整矩阵

Applying an adjustment matrix over each column of a timeseries-indexed DataFrame

我不熟悉应用矩阵计算,而且我尝试将以下复杂性因素应用于我的 DataFrame 中的 每个 数据点(以下值是所有上述变量值)。我已经尝试了 df.apply()np.dot()np.matrix() 的各种组合,但找不到方法(更不用说快速方法了!)来获得我需要的输出。

要应用的矩阵:

             0.6   0.3   0.1  (=1.0)
            |Low  |Med  |High
            ------------------
0.2   |Low  |1.1  |1.4  |2.0
0.4   |Med  |0.8  |1.0  |1.4
0.4   |High |0.6  |0.8  |1.1
(=1.0)

...所以我尝试应用的计算如下(如果 datapoint 为 500,调整后的结果将为 454):

 (<datapoint> * (0.2 * 0.6 * 1.1) + (0.2 * 0.3 * 1.4) + (0.2 * 0.1 * 2.0))
+(<datapoint> * (0.4 * 0.6 * 0.8) + (0.4 * 0.3 * 1.0) + (0.4 * 0.1 * 1.4))
+(<datapoint> * (0.4 * 0.6 * 0.6) + (0.4 * 0.3 * 0.8) + (0.4 * 0.1 * 1.1))

要应用于

的矩阵的DataFrame

要应用的此矩阵的 DataFrame 具有多级列。每列都是一个独立的系列,它运行在 DataFrame 的时间序列索引中(用 NaN 填充的空数据点)。

以下代码生成我正在试验的测试 DataFrame:

element=[]
role=[]

#Generate the Series'
element1_part1= pd.Series(abs(np.random.randn(5)), index=pd.date_range('01-01-2018',periods=5,freq='D'))
element.append('Element 1')
role.append('Part1')
element1_part2= pd.Series(abs(np.random.randn(4)), index=pd.date_range('01-02-2018',periods=4,freq='D'))
element.append('Element 1')
role.append('Part2')
element2_part1= pd.Series(abs(np.random.randn(2)), index=pd.date_range('01-04-2018',periods=2,freq='D'))
element.append('Element 2')
role.append('Part1')
element2_part2= pd.Series(abs(np.random.randn(2)),  index=pd.date_range('01-02-2018',periods=2,freq='D'))
element.append('Element 2')
role.append('Part2')
element3 = pd.Series(abs(np.random.randn(4)), index=pd.date_range('01-02-2018',periods=4,freq='D'))
element.append('Element 3')
role.append('Only Part')


#Zip the multi-level columns to Tuples
arrays=[element,role]
tuples = list(zip(*arrays))

#Concatenate the Series' and define timeseries
elements=pd.concat([element1_part1, element1_part2, element2_part1, element2_part2, element3], axis=1)
dateseries=elements.index

elements.columns=pd.MultiIndex.from_tuples(tuples, names=['Level-1', 'Level-2'])

如果我对问题的理解正确,您需要一个元素操作来更新 elements 数据框:

 (<datapoint> * [(0.2 * 0.6 * 1.1) + (0.2 * 0.3 * 1.4) + (0.2 * 0.1 * 2.0)])
+(<datapoint> * [(0.4 * 0.6 * 0.8) + (0.4 * 0.3 * 1.0) + (0.4 * 0.1 * 1.4)])
+(<datapoint> * [(0.4 * 0.6 * 0.6) + (0.4 * 0.3 * 0.8) + (0.4 * 0.1 * 1.1)])

对于所有 <datapoint>,此操作的形式为(x = <datapoint>):

[x * (a + b + c)] + [x * (d + e + f)] + [x * (g + h + i)] 
= x * (a + ... + i)
= Cx # for some constant C

这意味着您只需要计算标量值 C:

row_val = np.array([0.2, 0.4, 0.4])
col_val = np.array([0.6, 0.3, 0.1])

mat_val = np.matrix([[1.1, 1.4, 2.0], 
                     [0.8, 1.0, 1.4], 
                     [0.6, 0.8, 1.1]])

apply_mat = np.multiply(np.outer(row_val, col_val), mat_val)
apply_vec = np.sum(apply_mat, axis=1)
C = np.sum(apply_vec)
# 0.908

或"by hand":

print(((0.2 * 0.6 * 1.1) + (0.2 * 0.3 * 1.4) + (0.2 * 0.1 * 2.0)) +
      ((0.4 * 0.6 * 0.8) + (0.4 * 0.3 * 1.0) + (0.4 * 0.1 * 1.4)) +
      ((0.4 * 0.6 * 0.6) + (0.4 * 0.3 * 0.8) + (0.4 * 0.1 * 1.1)))
# 0.908

C 的这个值与您的示例数据点和预期输出相匹配:

0.908 * 500 = 454.0

现在您可以使用 mul():

elements.mul(C)

使用您的示例数据,这是输出:

Level-1    Element 1           Element 2           Element 3
Level-2        Part1     Part2     Part1     Part2 Only Part
2018-01-01  2.169116       NaN       NaN       NaN       NaN
2018-01-02  0.620286  1.645149       NaN  1.173356  0.277663
2018-01-03  0.782959  1.677798       NaN  0.557048  1.220138
2018-01-04  0.206314  0.773896  0.629524       NaN  0.572183
2018-01-05  1.209667  0.542614  0.666525       NaN  0.579032