代码之家  ›  专栏  ›  技术社区  ›  Mike T

使用来自另一个数组的唯一元素在值数组上应用函数

  •  1
  • Mike T  · 技术社区  · 7 年前

    idx 和一个值数组 val

    import numpy as np
    
    idx = np.array([[10, 10, 13],
                    [13, 10, 18],
                    [10, 16, 18]])
    
    np.random.seed(42)
    val = np.round(np.random.uniform(0, 100, 9).reshape((3, 3)), 1)
    
    print(repr(val))
    # array([[30.5,  9.8, 68.4],
    #        [44. , 12.2, 49.5],
    #        [ 3.4, 90.9, 25.9]])
    

    mean

    这是我最好的野蛮尝试 for -使用预期结果进行循环:

    {i: val[idx == i].mean() for i in np.unique(idx)}
    # {10: 13.975, 13: 56.2, 16: 90.9, 18: 37.7}
    

    虽然在本例中看起来不错,但在现实世界中,在一个包含500万个元素的阵列上,使用6000个唯一索引需要40秒以上的时间。这太长了,我正在寻找一种更有效的方法。

    1 回复  |  直到 7 年前
        1
  •  0
  •   jpp    7 年前

    对于大型阵列,即使在考虑了数据帧设置和从系列到字典的转换成本之后,您也会发现Pandas的效率更高:

    import numpy as np, pandas as pd
    # Python 3.7.0, Pandas 0.23.4, NumPy 1.15.1
    
    np.random.seed(0)
    n = 10**3
    idx = np.random.randint(0, 20, (n, n))
    val = np.random.random((n, n))
    
    df = pd.DataFrame({'idx': idx.ravel(), 'val': val.ravel()})
    
    %timeit pd.DataFrame({'idx': idx.ravel(), 'val': val.ravel()})  # 7.84 ms
    %timeit df.groupby('idx')['val'].mean()                         # 34.6 ms
    %timeit df.groupby('idx')['val'].mean().to_dict()               # 35.4 ms
    %timeit {i: val[idx == i].mean() for i in np.unique(idx)}       # 108 ms