2016-10-09 1 views
1

Я пытаюсь прочитать «n» каталоги/файлы данных, прочитать 7 столбцов из каждого каталога, а затем проверить, являются ли инструкции n * (n-1) «if» истинными, используя некоторые из 7 столбцов, прочитанных ранее. Если условие истинно, тогда сделайте некоторую математику, иначе ничего не делайте.Умный способ написать несколько вложенных циклов и операторов if в python.

Так, например, если я сравниваю два каталога, то у меня есть 2 инструкции «если» для тестирования, и если у меня есть 3 каталога, тогда у меня есть 6 «если» операторов для проверки.

Каждый каталог имеет примерно 10 000 строк и около 40 столбцов, но их длины в целом отличаются друг от друга.

В настоящее время у меня есть рабочий код для 3-х каталогов, где я читаю три каталога как вложенные для циклов и применяю свои 6 условий.

Вот пример моего кода:

path="xx" #Location of all input files. 
cat1 = ascii.read(path + file3, guess=False) 
data2 = fits.getdata(path+file2, 1) 
cat2 = Table(data2) 
cat3 = Table.read(path + 'xyz.tbl', format='ipac') 




for i in range(len(cat1)): 
    (ra1,dec1,flux1,flux1error,maj1,minor1,ang1)= (cat1['RA_Degrees'][i], 
cat1['DEC_Degrees'][i],cat1['fitted_total_flux'][i], 
cat1['fitted_total_flux_error'][i],cat1['BMajor_Degrees'][i], 
cat1['BMinor_Degrees'][i],cat1['position_angle_deg'][i]) 
    ang1=ang1*np.pi/180 



    for j in range(len(cat2)): 
     (ra2,dec2,total_cat2,total_error_cat2,maj2,min2,pa2)= (cat2['ra'][j],cat2['dec'][j], 
     cat2['total'][j],cat2['total_err'][j], 
     cat2['BMajor'][j],cat2['Bminor'][j],cat2['Position Angle'][j] 


     for k in range(len(cat3)): 
      (ra3,dec3,total_cat2,total_error_cat2,maj3,min3,pa3)=(cat3['ra'][k], 
      cat3['dec'][k],cat3['flux'][k],cat3['ferr'][k],cat3['bmaj'][k], 
      cat3['bmin'][k],cat3['pa'][k]) 

      if np.all(

      np.all(np.abs(ra2-ra1)< maj1+ maj2 and 

      np.all(np.abs(dec2-dec1)< maj1 + maj2) and 

      np.all(np.abs(ra3-ra2)< maj2 + maj3) and 

      np.all(np.abs(dec3-dec2)< maj2 + maj3) and 

      np.all(np.abs(ra3-ra1)< maj1 + maj3) and 

      np.all(np.abs(dec3-dec1)< maj1 + maj3) 

       ): 

У меня есть две проблемы, связанные с этим:

  1. Я хотел бы обобщить это на любое количество каталогов. В настоящее время мне нужно отредактировать код, если у меня есть 2,3,4 каталогов, которые раздражают.
  2. Для двух каталоговых совпадений требуется 33 минуты, но 3-х каталогичный код соответствия работает в течение 2 дней. Есть ли способ ускорить это.

Для первой проблемы я искал рекурсивные функции в приведенной ниже ссылке, но мой вопрос: могу ли я использовать это, так как число проверяемых условий также зависит от «n», а имена столбцов обычно не являются однородный по каталогам. Например: один каталог может вызвать «Право Вознесение» как «RA», другой каталог может называть его «ra» или «Right Ascension».

Basics of recursion in Python

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

https://docs.python.org/2/library/multiprocessing.html

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

ответ

1

Посмотрите на itertools. Это даст вам некоторые из основных инструментов для итерации списков столбцов с длиной списка, указанной в качестве параметра. Да, рекурсия помогает решить комбинаторику, но этот пакет будет обрабатывать накладные расходы рекурсии.

Конкретное понятием, которое Вы хотите для этого приложения является комбинацией из 7 колонок, взятая п в то время. Для иллюстрации рассмотрим 7 столбцов, взятых по 3 за раз: это в общей сложности 35 комбинаций: 7 * 6 * 5/3 * 2 * 1

Что вы получите, это генератор , a функция, которая будет возвращать каждую из 35 комбинаций в порядке сортировки по одному за раз. Затем вы можете перебирать это, как если бы это был список.Для каждой комбинации итерации через пары столбцов:

for col_list in combo_gen: 
    for right in range (1, n): 
     r_col = col_list[right] 
     for left in range(right): 
      l_col = col_list[left] 
      # Compare l_col and r_col 

Это основной план процесса. Вы можете взять его здесь?