сумма элементов списка в условиях второго списка

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

list1 = [4.0, 8.0, 14.0, 20.0, 22.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0] list2 = [2.1, 1.8, 9.5, 5., 5.4, 6.7, 3.3, 5.3, 8.8, 9.4, 5., 9.3, 3.1] 

Список 1 соответствует времени, поэтому я хочу, чтобы класть все каждые 10 [единиц времени], т. Е. Из списка1 я вижу, что первый и второй элементы принадлежат диапазону 0-10, поэтому мне нужно будет добавить их соответствующие точки в списке2. Позже из списка 1 я вижу, что третий и четвертый элементы относятся к диапазону (10 <time <= 20), поэтому я добавляю те же элементы в list2, позже для третьего диапазона, мне нужно добавить следующие 4 элемента в list3 и скоро. В конце я хотел бы создать 2 новых списка

 list3 = [10., 20., 30., 40.] list4 = [3.9, 14.5, 20.7, 35.6] 

Код, который я написал, следующий:

 list1 = [4.0, 8.0, 14.0, 20.0, 22.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0] list2 = [2.1, 1.8, 9.5, 5., 5.4, 6.7, 3.3, 5.3, 8.8, 9.4, 5., 9.3, 3.1] list3 = numpy.arange(0., 40., 10.) a = [[] for i in range(4)] for i, j in enumerate(list1): if 0.<=j<=10.: a[0].append(list2[i]) elif 10.<j<=20.: a[1].append(list2[i]) elif 20.<j<=30.: a[2].append(list2[i]) elif 30.<j<=40.: a[3].append(list2[i]) list4 = [sum(i) for i in a] 

он работает, однако, список1 на самом деле намного больше (на несколько порядков), и я не хочу писать все, если будет вручную (а также подписи, которые я делаю). Любые предложения будут оценены.

Прежде всего, если мы говорим о огромных наборах, я бы использовал numpy , pandas или другой инструмент, предназначенный для этого. По моему опыту, сам Python не предназначен для работы с вещами с более чем 10M элементами (если в данных, которые вы можете использовать, нет структуры).

Теперь мы можем использовать это следующим образом:

 import numpy as np # construct lists l1 = np.array(list1) l2 = np.array(list2) # determine the "groups" of the values g = (l1-0.00001)//10 # create a boolean mask that determines where the groups change flag = np.concatenate(([True], g[1:] != g[:-1])) # determine the indices of the swaps inv_idx, = flag.nonzero() # calculate the sum per subrange result = np.add.reduceat(list2,inv_idx) 

Для вывода вашего образца это дает:

 >>> result array([ 3.9, 14.5, 20.7, 35.6]) 

0.00001 используется для подталкивания от 20.0 до 19.9999 и поэтому назначает его группе 1 вместо группы 2. Преимущество этого подхода заключается в том, что (а) оно работает для произвольного числа «групп» и (б) фиксированного количество «прокруток» выполняется над списком, поэтому оно масштабируется линейно с количеством элементов в списке.

Если вы преобразуете свой список в numpy.array, есть простой способ извлечь некоторые вещи в 1D-массив на основе другого:

 import numpy list1 = numpy.array([4.0, 8.0, 14.0, 20.0, 22.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0]) list2 = numpy.array([2.1, 1.8, 9.5, 5., 5.4, 6.7, 3.3, 5.3, 8.8, 9.4, 5., 9.3, 3.1]) step = 10 r, s = range(0,50,10), [] for i in r: s.append(numpy.sum([l for l in list2[(list1 > i) & (list1 <= i+step)]])) print r[1:], s[:-1] #[10, 20, 30, 40] [3.9, 14.5, 20.7, 35.6] 

Редактировать В одной строке:

 s = [numpy.sum([l for l in list2[(list1 > i) & (list1 < i+step)]]) for i in r]