2013-03-29 6 views
0

Мой вопрос, вероятно, очень простой, но я не могу понять, способ сделать эту операцию быстрееМедленная работа массива в Python

print a[(b==c[i]) for i in arange(0,len(c))] 

где а, Ь и с тремя numpy массивами. Я имею дело с массивами с миллионами записей, а часть кода выше - узкое место моей программы.

+1

Чтобы ответить на этот вопрос ничего лучше, чем догадка мы должны были бы, по крайней мере форму а, Ь, с - векторы, матрицы и т.д. – jedwards

+0

а, b, c - 1D массивы – Brian

+1

В результате вашего кода возникает синтаксическая ошибка. Не могли бы вы показать небольшой рабочий пример медленного кода? –

ответ

4

Вы пытаетесь получить значения a где b==c?

Если да, то вы можете просто сделать a[b==c]:

from numpy import * 

a = arange(11) 
b = 11*a 
c = b[::-1] 

print a  # [ 0 1 2 3 4 5 6 7 8 9 10] 
print b  # [ 0 11 22 33 44 55 66 77 88 99 110] 
print c  # [110 99 88 77 66 55 44 33 22 11 0] 
print a[b==c] # [5] 
+0

спасибо за ответ, но это не совсем то, что я ищу. В вашем примере я хотел бы, чтобы результат был [10 9 8 7 6 5 4 3 2 1 0], потому что это значения a, где b = c – Brian

+1

@Matteo: Что, если b [j] == c [i] для нескольких значений i или j? – tom10

+0

Предположим, что повторений нет. Извините, мой вопрос был не очень подробным. – Brian

2

Возможно, вам стоит посмотреть в эфир. Я предполагаю, что вы ищете что-то вроде следующего?

>>> b=np.arange(5) 
>>> c=np.arange(6).reshape(-1,1) 
>>> b 
array([0, 1, 2, 3, 4]) 
>>> c 
array([[0], 
     [1], 
     [2], 
     [3], 
     [4], 
     [5]]) 
>>> b==c 
array([[ True, False, False, False, False], 
     [False, True, False, False, False], 
     [False, False, True, False, False], 
     [False, False, False, True, False], 
     [False, False, False, False, True], 
     [False, False, False, False, False]], dtype=bool) 
>>> np.any(b==c,axis=1) 
array([ True, True, True, True, True, False], dtype=bool) 

Ну для больших массивов, вы можете попробовать:

import timeit 

s=""" 
import numpy as np 
array_size=500 
a=np.random.randint(500, size=(array_size)) 
b=np.random.randint(500, size=(array_size)) 
c=np.random.randint(500, size=(array_size)) 
""" 

ex1=""" 
a[np.any(b==c.reshape(-1,1),axis=0)] 
""" 

ex2=""" 
a[np.in1d(b,c)] 
""" 

print 'Example 1 took',timeit.timeit(ex1,setup=s,number=100),'seconds.' 
print 'Example 2 took',timeit.timeit(ex2,setup=s,number=100),'seconds.' 

Когда ARRAY_SIZE составляет 50:

Example 1 took 0.00323104858398 seconds. 
Example 2 took 0.0125901699066 seconds. 

Когда ARRAY_SIZE составляет 500:

Example 1 took 0.142632007599 seconds. 
Example 2 took 0.0283041000366 seconds. 

Когда ARRAY_SIZE составляет 5000 :

Example 1 took 16.2110910416 seconds. 
Example 2 took 0.170011043549 seconds. 

Когда ARRAY_SIZE составляет 50000 (число = 5):

Example 1 took 33.0327301025 seconds. 
Example 2 took 0.0996031761169 seconds. 

Примечание я должен был изменить, какая ось для np.any(), так что результаты будут одинаковыми. Обратный порядок np.in1d ​​или ось переключения np.any для желаемого эффекта. Вы можете выполнить преобразование из примера 1, но изменить его можно довольно быстро. Переключитесь, чтобы получить желаемый эффект. Действительно интересно - мне придется использовать это в будущем.

+0

спасибо, что это то, что я ищу, но он довольно медленный для очень больших массивов. – Brian

+0

@Matteo: для 1 миллионного массива значений int, b == c - 1 триллион байт, поэтому он, вероятно, будет немного медленным. (Не отказать в этом ответе, но, прислуга и +1 к Ophion за правильное угадывание того, что вы ищете!) – tom10

+0

Добавлен более быстрый метод. @ tom10 Я был на 90% уверен, что он хотел, это ваше решение после того, как вы его разместили :). – Daniel

0

Как насчет np.where():

>>> a = np.array([2,4,8,16]) 
>>> b = np.array([0,0,0,0]) 
>>> c = np.array([1,0,0,1]) 
>>> bc = np.where(b==c)[0] #indices where b == c 
>>> a[bc] 
array([4,8]) 

Это должно сделать трюк. Не уверен, что если сроки является оптимальным для ваших целей

>>> a = np.random.randint(0,10000,1000000) 
>>> b = np.random.randint(0,10000,1000000) 
>>> c = np.random.randint(0,10000,1000000) 
>>> %timeit(a[ np.where(b == c)[0] ] ) 
100 loops, best of 3: 11.3 ms per loop 
Смежные вопросы