代码之家  ›  专栏  ›  技术社区  ›  SugaKookie

加快Python.loc函数搜索速度

  •  0
  • SugaKookie  · 技术社区  · 6 年前

    我从表中取出一个值,根据其他列中的匹配项搜索该值。现在,因为有几十万个网格单元需要处理,所以每次调用函数都需要几秒钟,但加起来需要几个小时。有没有更快的方法?

    data_1 = data.loc[(data['test1'] == test1) & (data['test2'] == X) & (data['Column'] == col1) & (data['Row']== row1)].Value
    

    样品 data

    Column  Row Value   test2   test1
    2       3   5       X       0TO4
    2       6   10      Y       100UP
    2       10  5.64    Y       10TO14
    5       2   9.4     Y       15TO19
    9       2   6       X       20TO24
    13      11  7.54    X       25TO29
    25      2   6.222   X       30TO34
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   frmsaul    6 年前

    test1 , test2 , Column Row

    索引:

    data.set_index(["test1", "test2", "Column", "Row"], inplace=True)
    

    data_1 = data.loc[(test1, X, col1, row1)].Value
    
        2
  •  1
  •   G. Anderson    6 年前

    这可能值得一读 enhancing performance docs 看看什么最适合你的需要。

    一种选择是使用 .values 和切片。在没有看到您的实际数据或用例的情况下,我创建了以下合成数据:

    data=pd.DataFrame({'column':[np.random.randint(30) for i in range(100000)],
                    'row':[np.random.randint(50) for i in range(100000)],
                    'value':[np.random.randint(100)+np.random.rand() for i in range(100000)],
                     'test1':[np.random.choice(['X','Y']) for i in range(100000)],
                    'test2':[np.random.choice(['d','e','f','g','h','i']) for i in range(100000)]})
    
    data.head()
    
        column  row value       test1   test2
    0   4       30  88.367151   X       e
    1   7       10  92.482926   Y       d
    2   1       17  11.151060   Y       i
    3   27      10  78.707897   Y       g
    4   19      35  95.204207   Y       h
    

    然后使用 %timeit .loc 索引、布尔掩蔽和numpy切片

    %timeit data_1 = data.loc[(data['test1'] == 'X') & (data['column'] >=12) & (data['row'] > 22)]['value']
    13 ms ± 538 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    %timeit data_1 = data[(data['test1'] == 'X') & (data['column'] >=12) & (data['row'] > 22)]['value']
    13.1 ms ± 233 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    现在,下一部分包含将数据帧转换为numpy数组的一些开销。如果只转换一次,然后对其进行多次查找,则速度会更快。但如果不是这样,您很可能会花费更长的时间进行单个转换/切片

    不考虑转换时间:

    d1=data.values
    
    %timeit d1[(d1[:,3]=='X')&(d1[:,0]>=12)&(d1[:,1]>22)][:,2]
    8.37 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    大约30%的改善

    转换时间:

    %timeit d1=data.values;d1[(d1[:,3]=='X')&(d1[:,0]>=12)&(d1[:,1]>22)][:,2]
    20.6 ms ± 624 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)