python numpy - Scipy griddata не работает внутри утечки цикла / памяти




interpolate 2d (2)

У меня проблема с использованием Gridata Scipy внутри цикла. В основном происходит то, что память растет без ограничений во время работы цикла.

Чтобы воспроизвести проблему, просто поставьте пример в

http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html

внутри цикла:

for i in range(100000):

    grid_z1 = griddata(points, values, (grid_x, grid_y), method='linear')

Моя версия Python - 2.7.3, моя версия numpy - 1.7.0, а моя scipy - 0.12.0b1. Я запускаю его на WIndows 7.

Это ошибка? Как я могу повторить интерполяцию много раз, не сталкиваясь с проблемой утечки памяти?

Остальная часть кода:

def func(x, y):
    return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2

grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j]
points = np.random.rand(1000, 2)
values = func(points[:,0], points[:,1])

for i in range(100000):

    grid_z1 = griddata(points, values, (grid_x, grid_y), method='linear')

Заранее спасибо.


Answers

Это ошибка в Cython , она должна работать в финальной версии Scipy 0.12.0.


Самое интересное в том, что первый символ идентификатора является особенным. После первого символа цифры от 0 до 9 соответствуют действительным для идентификаторов, но они не должны быть первым символом.

Вот функция, которая вернет действительный идентификатор, заданный любой случайной строкой символов. Вот как это работает:

Во-первых, мы используем itr = iter(seq) чтобы получить явный итератор на входе. Затем есть первый цикл, который использует итератор itr для просмотра символов до тех пор, пока не найдет допустимый первый символ для идентификатора. Затем он вырывается из этого цикла и запускает второй цикл, используя тот же самый итератор (который мы назвали itr ) для второго цикла. Итератор itr хранит наше место для нас; символы, которые первый цикл вытащил из итератора, все еще исчезают, когда выполняется второй цикл.

def gen_valid_identifier(seq):
    # get an iterator
    itr = iter(seq)
    # pull characters until we get a legal one for first in identifer
    for ch in itr:
        if ch == '_' or ch.isalpha():
            yield ch
            break
    # pull remaining characters and yield legal ones for identifier
    for ch in itr:
        if ch == '_' or ch.isalpha() or ch.isdigit():
            yield ch

def sanitize_identifier(name):
    return ''.join(gen_valid_identifier(name))

Это чистый и путинский способ обработки последовательности двумя разными способами. Для проблемы это просто, мы могли бы просто иметь логическую переменную, которая указывает, видели ли мы еще один символ или нет:

def gen_valid_identifier(seq):
    saw_first_char = False
    for ch in seq:
        if not saw_first_char and (ch == '_' or ch.isalpha()):
            saw_first_char = True 
            yield ch
        elif saw_first_char and (ch == '_' or ch.isalpha() or ch.isdigit()):
            yield ch

Мне не нравится эта версия почти так же, как и первая версия. Специальная обработка для одного символа теперь запуталась во всем потоке управления, и это будет медленнее, чем первая версия, поскольку она должна постоянно проверять значение saw_first_char . Но именно так вы должны были бы управлять потоком управления на большинстве языков! Явный итератор Python - отличная функция, и я думаю, что этот код намного лучше.

Looping на явном итераторе выполняется так же быстро, как позволить Python неявно получить для вас итератор, а явный итератор позволяет нам разделить циклы, которые обрабатывают разные правила для разных частей идентификатора. Таким образом, явный итератор дает нам более чистый код, который также работает быстрее. Win / выигрыш.





python scipy interpolation