【问题标题】:How to melt a dataframe while doing some operation?如何在进行某些操作时融化数据框?
【发布时间】:2021-01-29 08:59:31
【问题描述】:

假设我有以下数据框:

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() 函数,虽然它让我更接近我想要的,但它并没有完全让我到达我想要的地方。能给我一个提示吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这是矩阵乘法:

    (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
    

    【讨论】:

    • 相反,由于矩阵乘法是许多应用程序的核心,人们花费大量时间优化它。请放心,它是最有效的操作之一:-)。
    • 很好的答案 - 我想我现在明白如何做到这一点了。很简单,谢谢!看起来左边的矩阵是水平的,而右边的矩阵是垂直的。您也可以通过相反的方式解决问题(转置另一个矩阵/数据框并从右到左交换),但您需要排序:(df[['K1','K2']].T@df[['D1','D2','D3']]).unstack().reset_index()
    • 太棒了!非常感谢!
    • @Skyris 查看我的答案,这是 QuangHoang 的性能答案的 numpy 版本。这是我第一次做矩阵乘法,所以 Quang Hoang,请随时在我的答案中输入一些内容。如果它更快,您仍然可以将其保留为已接受的答案,因为我建立了 Quang 的答案。
    【解决方案2】:

    以@QuangHoang 的回答为基础,您可以查看 numpy .dot 矩阵乘法版本是否更高效。由于.to_numpy() 只是创建了一个与KD 索引无关的数字矩阵,因此除了纯数字之外,您还必须进行一些操作才能将其恢复为您想要的熊猫格式:

    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()
    

    更多信息 (numpy matrix vector multiplication)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 2012-12-07
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多