代码之家  ›  专栏  ›  技术社区  ›  Stücke

警察局。连载到pd。数据帧,同时将每个元素与其他元素相乘

  •  0
  • Stücke  · 技术社区  · 3 年前

    假设我有一个向量 | a | b | c | d | ,例如。

    vec = pd.Series([0.3,0.2,0.2,0.3])
    

    什么是快速而优雅的方式来构建一个 pd.DataFrame 形式如下:

    | a*a | a*b | a*c | a*d |
    | b*a | b*b | b*c | b*d |
    | c*a | c*b | c*c | c*d |
    | d*a | d*b | d*c | d*d |
    
    2 回复  |  直到 3 年前
        1
  •  3
  •   enke    3 年前

    一种选择是使用 dot :

    fr = vec.to_frame()
    out = fr.dot(fr.T)
    

    输出:

          0     1     2     3
    0  0.09  0.06  0.06  0.09
    1  0.06  0.04  0.04  0.06
    2  0.06  0.04  0.04  0.06
    3  0.09  0.06  0.06  0.09
    
        2
  •  2
  •   jezrael    3 年前

    使用numpy广播:

    vec = pd.Series([0.3,0.2,0.2,0.3])
    
    a = vec.to_numpy()
    
    df = pd.DataFrame(a * a[:, None], index=vec.index, columns=vec.index)
    print (df)
          0     1     2     3
    0  0.09  0.06  0.06  0.09
    1  0.06  0.04  0.04  0.06
    2  0.06  0.04  0.04  0.06
    3  0.09  0.06  0.06  0.09
    

    numpy.outer :

    df = pd.DataFrame(np.outer(vec, vec), index=vec.index, columns=vec.index)
    print (df)
          0     1     2     3
    0  0.09  0.06  0.06  0.09
    1  0.06  0.04  0.04  0.06
    2  0.06  0.04  0.04  0.06
    3  0.09  0.06  0.06  0.09
    

    表演 (如果在评论中提到@enke,这很重要):

    np.random.seed(2022)
    vec = pd.Series(np.random.rand(10000))
    
    print (vec)
    
    
    In [39]: %%timeit
        ...: fr = vec.to_frame()
        ...: out = fr.dot(fr.T)
        ...: 
    386 ms ± 13.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [40]: %%timeit
        ...: pd.DataFrame(np.outer(vec, vec), index=vec.index, columns=vec.index)
        ...: 
        ...: 
    351 ms ± 2.62 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [41]: %%timeit
        ...: a = vec.to_numpy()
        ...: 
        ...: df = pd.DataFrame(a * a[:, None], index=vec.index, columns=vec.index)
        ...: 
    293 ms ± 4.22 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)