Найти - Пользователи
Полная версия: numpy оптимизация
Начало » Python для экспертов » numpy оптимизация
1 2 3
marina932
 list(zip(*np.unique(text, return_counts=True)))
Можно ли как-то оптимизировать этот код (может быть распараллелить?), а то на массиве из 100 000 000 программа на этом месте застревает на 10 секунд, если возможно хотелось бы быстрее.
noob_saibot
У вас на входе numpy массив? или вы так назвали список?
Вам там точно list нужен?
Может zip на dstack поменять?

PS. Нужно больше кода.
doza_and
noob_saibot
PS. Нужно больше кода.
И данных :)
marina932 проведите дальше декомпозицию - определите доли в этих 10 секундах list(zip(*)) и unique.

Вопрос возникает потому что непонятно что такое text.

Оптимизация в вашем случае если и возможна, то только изменением входных и выходных данных надо менять объемлющий алгоритм.
вот вам код на подумать
 #include <iostream>
#include <iomanip>
using namespace std;
const int N=100000000;
const int M=256;
static unsigned char arr[N];
int main()
{
    int count[M]={0};
    int i;
    for(i=0;i<N;++i){arr[i]=i;}
    for(i=0;i<N;++i){++count[arr[i]];}
    for(i=0;i<M;++i)
    {
        cout<<count[i]<<endl;
    }
    cout<<"done"<<endl;
    return 0;
}

он на слабеньком ноутбуке выполнется меньше секунды.
marina932
alphabet состоит из 10 символов, size = 100 000 000
 text = np.random.choice(list(alphabet.keys()), p=list(alphabet.values()), size=length)

noob_saibot
Может zip на dstack поменять?
Мне кажется нет смысла, потому на выходе у меня всего 10 символов будет + для каждого будет указана частота появления в коде.
marina932
doza_and
Си это конечно хорошо и быстро, но хотел обойтись python, на нем все таки пишу.
noob_saibot
marina932
doza_andСи это конечно хорошо и быстро, но хотел обойтись python, на нем все таки пишу.
Вы же в курсе почему doza_and написал на си?
marina932
noob_saibot
Да знаю, что можно расширения на си писать, но все же не хотелось бы это делать. Если без этого ни как вообще, то думаю лучше будет cython использовать.
marina932
В общем частично решила проблему тем, что теперь считаю частоту появления символов не в итоговом массиве, а у каждой части общего массива, который генерится в отдельном потоке.
izekia
У меня машина медленная, поэтому результаты по абсолютному времени могут различаться:
 import random
import numpy as np
def create_text(length):
    alphabet = {str(i-1): np.float64(i / 55.0) for i in range(1, 11)}
    return np.random.choice(list(alphabet.keys()), p=list(alphabet.values()), size=length)
text = create_text(100000000)
text, len(text)
(array(,
dtype='<U1'), 100000000)
 def f_prev(text):
    l1 = np.unique(text, return_counts=True)
    l2 = zip(*l1)
    l3 = {code: count for code, count in l2}
    return l3
 def f_view(text):
    l1 = np.unique(text.view(np.int), return_counts=True)
    l2 = zip(*l1)
    l3 = {chr(code): count for code, count in l2}
    return l3
 f_prev(text)
{'0': 1820740,
‘1’: 3636051,
‘2’: 5458589,
‘3’: 7271355,
‘4’: 9086383,
‘5’: 10906851,
‘6’: 12728655,
‘7’: 14542164,
‘8’: 16360778,
‘9’: 18188434}
 f_prev(text) == f_view(text)
True
 %%timeit -n 5
f_prev(text)
5 loops, best of 3: 21.3 s per loop
 %%timeit -n 5
f_view(text)
5 loops, best of 3: 8.16 s per loop

PS: чуть позже может через сифон другой вариант попробую, но нет уверенности что будет много быстрее
izekia
странно, а я думал, что все методы numpy дико оптимизированы:
 %%cython -a 
#cython: boundscheck=False
import numpy as np
cimport numpy as np
cpdef trivial1_cyth1(text):
    cdef int[:] text_int_view = text.view(np.int)
    cdef int[:] c = np.zeros(256, dtype=np.int)
    cdef int l = len(text_int_view )
    cdef int i
    for i in range(l):
        c[text_int_view [i]] += 1
    return {chr(i): c[i] for i in range(len(c)) if c[i] > 0}

 text, len(text)
(array(,
dtype='<U1'), 100000000)
 %%timeit
trivial1_cyth1(text)
1 loop, best of 3: 375 ms per loop
 def f_prev(text):
    l1 = np.unique(text, return_counts=True)
    l2 = zip(*l1)
    l3 = {code: count for code, count in l2}
    return l3
 %%timeit -n 5
f_prev(text)
5 loops, best of 3: 24.3 s per loop
 res = trivial1_cyth1(text)
res_prev = f_prev(text)
res == res_prev
True
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB