Ускорить поиск функции Python .loc - PullRequest
0 голосов
/ 08 января 2019

Я вытаскиваю значение из таблицы, ищу значение на основе совпадений в других столбцах. Прямо сейчас, потому что нужно пройти сотни тысяч ячеек сетки, каждый вызов функции занимает несколько секунд, но это в сумме составляет часы. Есть ли более быстрый способ сделать это?

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 ]

0 голосов
/ 08 января 2019

Может быть стоит прочитать краткое описание документации по повышению производительности , чтобы узнать, что лучше всего соответствует вашим потребностям.

Один из вариантов - перейти к numpy, используя .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 индексацию, логическое маскирование и нарезку кусков (Обратите внимание, в этот момент я понял, что пропустил один из поисков, так что это может повлиять на общее количество времени, но коэффициенты должны сохраняться)

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

Теперь эта следующая часть содержит некоторые накладные расходы на преобразование кадра данных в пустой массив. Если вы конвертируете его один раз, а затем выполняете несколько поисков, тогда это будет быстрее. Но если нет, то вам, вероятно, понадобится больше времени для одного преобразования / среза

Без учета времени конвертации:

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)

Приблизительно на 50% хуже

0 голосов
/ 08 января 2019

Вы можете индексировать по test1, test2, Column и Row, а затем искать по этому индексу.

Индексация:

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

, а затем ищите, выполнив это:

data_1 = data.loc[(test1, X, col1, row1)].Value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...