Supongamos que tengo una matriz de Python a=[3, 5, 2, 7, 5, 3, 6, 8, 4] . Mi objetivo es iterar a través de esta matriz 3 elementos a la vez devolviendo la media de los 2 primeros de los tres elementos.
Usando la matriz anterior, durante mi paso de iteración, los primeros tres elementos son [3, 5, 2] y la media de los 2 elementos superiores es 4. Los siguientes tres elementos son [5, 2, 7] y la media de los los 2 elementos superiores es 6. Los siguientes tres elementos son [2, 7, 5] y la media de los 2 elementos superiores es nuevamente 6. ...
Por lo tanto, el resultado de la matriz anterior sería [4, 6, 6, 6, 5.5, 7, 7] .
¿Cuál es la mejor manera de escribir tal función?
Puede usar algunos cortes elegantes de su lista para manipular subconjuntos de elementos. Simplemente tome cada sublista de tres elementos, ordene para encontrar los dos elementos principales y luego encuentre el promedio simple (también conocido como media) y agréguelo a una lista de resultados.
def get_means(input_list): means = [] for i in xrange(len(input_list)-2): three_elements = input_list[i:i+3] sum_top_two = sum(three_elements) - min(three_elements) means.append(sum_top_two/2.0) return meansPuede ver su entrada de ejemplo (y el resultado deseado) así:
print(get_means([3, 5, 2, 7, 5, 3, 6, 8, 4])) # [4.0, 6.0, 6.0, 6.0, 5.5, 7.0, 7.0]Hay algunas otras respuestas excelentes que se convierten en respuestas más dirigidas al rendimiento, incluida una que usa un generador para evitar grandes listas de memoria: https://stackoverflow.com/a/49001728/416500
Creo en dividir el código en 2 partes. Aquí, eso sería obtener la ventana deslizante, obtener los 2 elementos principales y calcular la media. La forma más limpia de hacer esto es usando generadores.
Ligera variación en la respuesta de evamicur usando tee , islice y zip para crear la ventana:
def windowed_iterator(iterable, n=2): iterators = itertools.tee(iterable, n) iterators = (itertools.islice(it, i, None) for i, it in enumerate(iterators)) yield from zip(*iterators) windows = windowed_iterator(iterable=a, n=3)[(3, 5, 2), (5, 2, 7), (2, 7, 5), (7, 5, 3), (5, 3, 6), (3, 6, 8), (6, 8, 4)]
para calcular la media de los 2 mas altos puedes usar cualquiera de los metodos usados en las otras respuestas, creo que el heapq on es el mas claro
from heapq import nlargest top_n = map(lambda x: nlargest(2, x), windows)o equivalente
top_n = (nlargest(2, i) for i in windows)[[5, 3], [7, 5], [7, 5], [7, 5], [6, 5], [8, 6], [8, 6]]
from statistics import mean means = map(mean, top_n)[4, 6, 6, 6, 5.5, 7, 7]
El siguiente código hace lo que necesitas:
[sum(sorted(a[i:i + 3])[-2:]) / 2 for i in range(len(a) - 2)] Dado su a=[3, 5, 2, 7, 5, 3, 6, 8, 4] , devuelve:
[4.0, 6.0, 6.0, 6.0, 5.5, 7.0, 7.0]