#python #python-3.x #list #algorithm #performance
#python #python-3.x #Список #алгоритм #Производительность
Вопрос:
Какой наиболее эффективный способ объединить эти списки в один список, где конечные значения являются максимальными из каждого списка, поддерживающего позицию? Прямо сейчас я выполняю перебор всех списков и устанавливаю максимальное значение в конечном списке. Это работает, но не очень эффективно, поскольку мои наборы данных огромны. Есть идеи о том, как сделать это более эффективным?
graph1 = [[0, 0, 0], [1, 0, 1], [2, 0, 0]]
graph2 = [[5, 0, 0], [1, 0, 1], [2, 0, 0]]
graph3 = [[2, 1, 0], [0, 0, 1], [0, 0, 0]]
graph4 = [[1, 0, 1], [9, 0, 0], [2, 0, 0]]
graphs = [graph1, graph2, graph3, graph4]
# TODO, what's the most efficient way to merge these lists into one single list where the final values are the max from each list maintaining position?
# desiredResultGraph = [[5, 1, 1], [9, 0, 1], [2, 0, 0]]
Обновленное решение, основанное на решении Марка Мейера, приведенном ниже:
graph = np.ndarray(shape=(4, 3, 3), dtype=float, order='F')
graph[0] = [[0, 0, 1], [1, 0, 1], [2, 0, 0]]
graph[1] = [[0, 0, 1], [1, 0, 1], [2, 0, 0]]
graph[2] = [[5, 0, 0], [1, 0, 1], [2, 0, 0]]
graph[3] = [[2, 1, 0], [9, 0, 1], [0, 0, 0]]
PrintAndLog("graph of type " str(type(graph)) " = " str(graph))
resultGraph = graph.max(axis=0)
PrintAndLog("resultGraph of type " str(type(resultGraph)) " = " str(resultGraph))
Вывод:
graph of type <class 'numpy.ndarray'> =
[[[ 0. 0. 1.]
[ 1. 0. 1.]
[ 2. 0. 0.]]
[[ 0. 0. 1.]
[ 1. 0. 1.]
[ 2. 0. 0.]]
[[ 5. 0. 0.]
[ 1. 0. 1.]
[ 2. 0. 0.]]
[[ 2. 1. 0.]
[ 9. 0. 1.]
[ 0. 0. 0.]]]
resultGraph of type <class 'numpy.ndarray'> =
[[ 5. 1. 1.]
[ 9. 0. 1.]
[ 2. 0. 0.]]
Комментарии:
1. Вы можете сделать
[[max(i) for i in zip(*v)] for v in zip(*graphs)]
, но использованиеnumpy
, как правило, будет быстрее.2. @AndrejKesely Понял. Итак, допустим, я начинаю с 4 отдельных массивов numpy вместо 4 отдельных списков, как я могу выполнить эту команду, которую вы предложили вместо объединения этих numpy arrarys?
Ответ №1:
Если вы работаете с большими наборами числовых данных, вам будет сложно превзойти производительность Numpy. И это упрощает такие вещи:
import numpy as np
graph1 = [[0, 0, 0], [1, 0, 1], [2, 0, 0]]
graph2 = [[5, 0, 0], [1, 0, 1], [2, 0, 0]]
graph3 = [[2, 1, 0], [0, 0, 1], [0, 0, 0]]
graph4 = [[1, 0, 1], [9, 0, 0], [2, 0, 0]]
np.array([graph1, graph2, graph3, graph4]).max(axis = 0)
Результат:
array([[5, 1, 1],
[9, 0, 1],
[2, 0, 0]])
Комментарии:
1. Мне нравится это решение за его элегантность. Но я действительно сомневаюсь, что это самый быстрый. np.array(….) необходимо создать новый массив, скопировав все данные из существующих массивов, и все это для выполнения тривиальной операции.
2. Я думаю, это справедливо @FrankYellin. Я подозреваю, что если OP действительно работает с массивными данными, в их интересах попытаться начать с массивов numpy с самого начала.
3. Я проверю это, а также посмотрю, что потребуется для преобразования моих списков python в массивы numpy везде, чтобы убедиться, что я не убиваю свою производительность.
4. @FrankYellin Итак, даже если я начну с numpy-массива вместо списка, если я использую np.array() и передам ему numpy-массивы, он все равно будет копировать (что неэффективно), верно?
5. @LampShade, если вы начинаете с массива numpy, это будет просто
some_array.max(axis = 0)
, что будет очень эффективно.