假设我具有以下数据框:
index K1 K2 D1 D2 D3
N1 0 1 12 4 6
N2 1 1 10 2 7
N3 0 0 3 5 8
基本上,我想将此数据帧转换为以下内容:
index COL1 COL2
K1 D1 = 0*12+1*10+0*3
K1 D2 = 0*4+1*2+0*5
K1 D3 = 0*6+1*7+0*8
K2 D1 = 1*12+1*10+0*3
K2 D2 = 1*4+1*2+0*5
K2 D3 = 1*6+1*7+0*8
COL2
的内容基本上是index
中的向量和COL1
中的向量之间的点积(也称为标量积)。例如,让我们以结果df的第一行为例。在index
下,我们有K1
,在COL1
下,我们有D1
。查看第一张表,我们知道K1 = [0,1,0]
和D1 = [12,10,3]
。这两个“向量”的标量积是COL2
(第一行)中的值。
我试图找到一种不使用嵌套循环的方法(因为这样做是为了提高效率),但是,我不知道怎么做。我尝试使用pd.melt()
函数,尽管它使我更接近想要的东西,但并不能使我到达想要的位置。你能给我一个提示吗?
答案 0 :(得分:7)
这是矩阵乘法:
(df[['D1','D2','D3']].T@df[['K1','K2']]).unstack().reset_index()
输出:
level_0 level_1 0
0 K1 D1 10
1 K1 D2 2
2 K1 D3 7
3 K2 D1 22
4 K2 D2 6
5 K2 D3 13
答案 1 :(得分:1)
根据@QuangHoang的答案,您可以看到numpy .dot
矩阵乘法版本的性能是否更高。由于.to_numpy()
只是创建了一个数字矩阵,该数字矩阵与K
和D
索引没有关系,因此除了纯数字之外,您还需要进行一些操作以使其恢复为您想要的熊猫格式:
a1 = df[['D1','D2','D3']].T.to_numpy()
a2 = df[['K1','K2']].to_numpy()
df1 = pd.DataFrame(a1.dot(a2)).unstack().reset_index() #see other options below
df1['level_0'] = 'K' + (df1['level_0'] + 1).astype(str)
df1['level_1'] = 'D' + (df1['level_1'] + 1).astype(str)
df1
Out[1]:
level_0 level_1 0
0 K1 D1 10
1 K1 D2 2
2 K1 D3 7
3 K2 D1 22
4 K2 D2 6
5 K2 D3 13
其他numpy
个数组选项:
df1 = pd.DataFrame(a1 @ a2).unstack().reset_index()
df1 = pd.DataFrame(np.matmul(a1, a2)).unstack().reset_index()