2013-01-03 3 views
0

У меня есть довольно большой набор данных, который я храню в HDF5 и доступ с помощью PyTables. Одной операцией, которую мне нужно сделать в этом наборе данных, является попарное сравнение между каждым из элементов. Для этого требуется 2 цикла, один для итерации по каждому элементу и внутренний цикл для итерации по каждому другому элементу. Таким образом, эта операция рассматривает сравнения N (N-1)/2.Вложенная итерация HDF5 с использованием PyTables

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

Ввод элементов в массив дает мне около 600 сравнений в секунду, а сама работа с данными hdf5 дает мне около 300 сравнений в секунду.

Есть ли способ ускорить этот процесс?

Пример следующим образом (это не мой реальный код, просто пример):

Small Set:

with tb.openFile(h5_file, 'r') as f: 
    data = f.root.data 

    N_elements = len(data) 
    elements = np.empty((N_elements, 1e5)) 

    for ii, d in enumerate(data): 
     elements[ii] = data['element'] 

D = np.empty((N_elements, N_elements)) 
for ii in xrange(N_elements): 
    for jj in xrange(ii+1, N_elements):    
     D[ii, jj] = compare(elements[ii], elements[jj]) 

Большой набор:

with tb.openFile(h5_file, 'r') as f: 
    data = f.root.data 

    N_elements = len(data)   

    D = np.empty((N_elements, N_elements)) 
    for ii in xrange(N_elements): 
     for jj in xrange(ii+1, N_elements):    
      D[ii, jj] = compare(data['element'][ii], data['element'][jj]) 

ответ

0

Два подхода I 'd предложить здесь:

  1. numpy memmap: Создайте массив с отображением памяти, поместите данные внутри этого и затем запустите код для «Малый набор». Карты памяти ведут себя почти как массивы.

  2. Используйте многопроцессорный модуль для параллельной обработки: если метод «сравнения» потребляет хотя бы заметное количество процессорного времени, вы можете использовать несколько процессов.

Предполагая, что у вас есть несколько ядер в процессоре, это значительно ускорит работу. Используйте

  • один процесс чтения данных из HDF и положить в в очередь
  • один процесс, чтобы захватить из очереди и сделать comparisson и поставить какой-то результат на «выходную очередь»
  • один чтобы снова собрать результаты.

Прежде чем выбрать способ: «Знай своего врага», т. Е. Используйте профилирование! Оптимизации стоит только, если вы улучшаете узкие места, поэтому сначала узнайте, какие методы потребляют вам драгоценное время процессора.

Ваш алгоритм O (n^2), что плохо для больших данных. Разве вы не видите каких-либо шансов уменьшить это, например, применив некоторую логику? Это всегда лучший подход.

Привет,

Торстен

+0

Благодаря Торстен. Раньше я пробовал код профилирования, но, честно говоря, у меня были проблемы с интерпретацией результатов. Я попробую снова.Но я чувствую, что узкое место не должно иметь ничего общего с функцией сравнения, так как это делает то же самое на малых и больших реализациях. Это как-то связано с тем, как PyTables обращается к элементам. Кроме того, вы видите шанс уменьшить из O (n^2)? Каждый элемент уникален, поэтому я не вижу, как его можно улучшить, чем это, но я мог бы что-то упустить. – dvreed77

Смежные вопросы