Допускается поэлементное среднее значение списка, содержащего списки различной длины - PullRequest
0 голосов
/ 08 июля 2019

У меня есть код, где есть список X добавляет несколько списков разной длины.Например: окончательное значение X после запуска может выглядеть следующим образом:

X = [[0.6904056370258331, 0.6844439387321473, 0.668782365322113], 
     [0.7253621816635132, 0.6941058218479157, 0.6929935097694397, 0.6919471859931946, 0.6905447959899902]]

Как видите, X[0] имеет длину = 3, а X[1] имеет длину = 5.Я хочу сделать поэлементное (по столбцу) среднее значение X, чтобы сгенерировать одно 1D среднее значение X.Если я попытаюсь np.mean(X, axis=0), это вызовет ошибку, так как X[0] и X[1] имеют разную длину.Есть ли способ достичь того, что я ищу, то есть одно 1D среднее значение X?

Спасибо,

Ответы [ 2 ]

2 голосов
/ 08 июля 2019

Чтобы выполнить вычисления «столбцов», нам нужно изменить это на список столбцов.

In [475]: X = [[0.6904056370258331, 0.6844439387321473, 0.668782365322113],  
     ...:      [0.7253621816635132, 0.6941058218479157, 0.6929935097694397, 0.6919471859931946, 0.6905447959899902]] 

zip_longest - удобный инструмент для «переноса» нерегулярных списков:

In [476]: import itertools                                                                                   
In [477]: T = list(itertools.zip_longest(*X, fillvalue=np.nan))                                              
In [478]: T                                                                                                  
Out[478]: 
[(0.6904056370258331, 0.7253621816635132),
 (0.6844439387321473, 0.6941058218479157),
 (0.668782365322113, 0.6929935097694397),
 (nan, 0.6919471859931946),
 (nan, 0.6905447959899902)]

Я выбрал np.nan в качестве заливки, потому что затем могу использовать np.nanmean для получения среднего значения, игнорируя nan.

In [479]: [np.nanmean(i) for i in T]                                                                         
Out[479]: 
[0.7078839093446732,
 0.6892748802900315,
 0.6808879375457764,
 0.6919471859931946,
 0.6905447959899902]

Для чего-то вроде np.sum я мог бы заполнить 0, но mean - это сумма, деленная на количество.

Или без nanmean, заполните что-то, что легко отфильтровать:

In [480]: T = list(itertools.zip_longest(*X, fillvalue=None)) 
In [483]: [np.mean([i for i in row if i is not None]) for row in T]                                          
Out[483]: 
[0.7078839093446732,
 0.6892748802900315,
 0.6808879375457764,
 0.6919471859931946,
 0.6905447959899902]

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

0 голосов
/ 08 июля 2019

Как насчет этого

сначала определяют максимальную длину строки, затем заполните все строки одинаковой длины с помощью nans и используйте nanmean с осью = 0, как в вопросе.

import numpy as np
X = [[0.6904056370258331, 0.6844439387321473, 0.668782365322113], 
     [0.7253621816635132, 0.6941058218479157, 0.6929935097694397, 0.6919471859931946, 0.6905447959899902]]

max_row_len=max([len(ll) for ll in X])

cm=np.nanmean([[el for el in row ] + [np.NaN] * max(0, max_row_len-len(row))  for row in X], axis=0)

print(cm)

будет отображаться

[0,70788391 0,68927488 0,68088794 0,69194719 0,6905448]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...