Стандартизировать массив 3D NumPy, дополненный np.nan

У меня есть 3D-матрица формы (100, 40, 170).

Эта матрица была дополнена для достижения максимальной длины 170 путем заполнения np.nan (NaN).

Значения в матрице представляют собой коэффициенты MFCC из аудиоданных, извлеченных из набора данных UrbanSound8K с использованием LibRosa ( Питон).

(Исходный блокнот и данные являются общими, проверьте конец сообщения)

Мне нужно нормализовать эту матрицу по оси = 2:

  1. Вычислите среднее значение по 3-й оси, игнорируя элементы, равные np.nan
  2. Вычислить стандартное отклонение по 3-й оси, игнорируя элементы, равные np.nan
  3. Вычтите среднее значение для каждого элемента, который не равен np.nan
  4. Разделите на std dev каждый элемент, который не равен np.nan

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

# Compute mean and std dev matrices (omitting NaN and keeping shapes)
mean = np.nanmean(X_nan, axis=2, keepdims=True)
std = np.nanstd(X_nan, axis=2, keepdims=True)

Но затем, когда я вычитаю и делю, я получаю ошибки:

X_norm -= mean
X_norm /= std

В предупреждающем сообщении говорится:

RuntimeWarning: divide by zero encountered in true_divide

И когда я проверяю только первые элементы нормализованной и исходной матриц, я вижу:

# Original
array([[[-58.95327, -58.95327,        -58.95327,       ...,          
                     nan,             nan,            nan],

# Normalized
array([[[-inf,       -inf,            -inf,            ...,
                     inf,             inf,             inf],

Обратите внимание, что значения -inf вводятся при вычитании среднего, а не при делении.

Можете ли вы порекомендовать мне способ вычисления обеих метрик и выполнения вычитания и деления с помощью NumPy, опуская дополненные значения?

Большое спасибо!

Данные были созданы с помощью этого блокнота (обратите внимание, что репозиторий находится в разработке!): Классификация городских звуков с помощью CNN

Я загрузил данные (выделенные X и Y): Коэффициенты MFCC X и Y


person Eduardo G.R.    schedule 24.07.2019    source источник
comment
Это может быть идеальным приложением для замаскированных массивов.   -  person Linuxios    schedule 24.07.2019
comment
Можете ли вы опубликовать промежуточные значения, пожалуйста?   -  person Nils Werner    schedule 24.07.2019
comment
@Linuxios Я читал об использовании маски, но я также пытаюсь найти правильный способ сделать это с этим.   -  person Eduardo G.R.    schedule 25.07.2019
comment
@NilsWerner Конечно, я добавил еще несколько примеров.   -  person Eduardo G.R.    schedule 25.07.2019
comment
Все ваши значения почти одинаковы, неудивительно, что stddev равно нулю. Происходит ли то же самое со случайным трехмерным тензором?   -  person Szymon Maszke    schedule 25.07.2019
comment
@SzymonMaszke Привет, да, в этих примерах данные очень похожи, но не для всех элементов (сейчас я обновлю их). И да, с тензорами, у которых нет значений заполнения NaN, все работает нормально.   -  person Eduardo G.R.    schedule 25.07.2019
comment
@ ЭдуардоГ.Р. Все ваши значения в нормализованном массиве равны np.inf? И вы уверены, что это происходит после вычитания среднего?   -  person Szymon Maszke    schedule 25.07.2019
comment
@SzymonMaszke Да. В некоторых предыдущих попытках я не получил значения -inf, но результат все равно не был ожидаемым. Я думаю, что должен быть простой способ нормализовать матрицу с более чем двумя измерениями, опуская все элементы, введенные дополнением (в данном случае со значением np.nan)   -  person Eduardo G.R.    schedule 25.07.2019
comment
Скорее всего, это связано с тем, что значения в целом очень близки друг к другу и mean - element приближаются к числовой точности. Для stddev вы далее делите это значение на количество элементов и берете sqrt из того, что ниже этого порога. Вы должны сравнить рассчитанное среднее значение со значениями и посмотреть, сколько осталось после вычитания. И если mean достаточно близко к нулю, просто введите ноль. Что это за данные вообще, выглядит довольно странно   -  person Szymon Maszke    schedule 25.07.2019
comment
@SzymonMaszke это коэффициенты MFCC из аудиосэмплов. Был использован Padded, потому что все аудиофайлы имеют разную продолжительность. Существует множество различных теорий о том, как нормализовать MFCC, и многие даже говорят, что иногда нормализация MFCC на самом деле не требуется. Но я хотел бы провести свои собственные эксперименты и посмотреть, как одна и та же архитектура режима работает со стандартными и нормализованными данными, обучаясь в течение того же количества эпох.   -  person Eduardo G.R.    schedule 25.07.2019
comment
Если приведенные выше советы не помогли, вам лучше предоставить нам образец данных, порождающий такое поведение, чтобы мы могли провести собственное расследование. Вы можете опубликовать ссылку для загрузки сохраненного тензора в формате .npz или какого-нибудь рассола.   -  person Szymon Maszke    schedule 25.07.2019
comment
@SzymonMaszke Конечно! позвольте мне вернуться домой, и я подготовлю блокнот и некоторые сохраненные данные, спасибо за вашу помощь!   -  person Eduardo G.R.    schedule 25.07.2019
comment
@SzymonMaszke еще раз привет, я только что обновил пост с блокнотом и данными о рассоле, если вы хотите поэкспериментировать с ним, спасибо!   -  person Eduardo G.R.    schedule 25.07.2019
comment
Давайте продолжим это обсуждение в чате.   -  person Szymon Maszke    schedule 25.07.2019


Ответы (1)


Пожалуйста, попробуйте это решение:

X_norm = np.where(np.isnan(X_nan), np.nan, X_nan - mean)
X_norm = np.where(X_norm == 0, 0, X_norm/std)

также дать предупреждение, но похоже, что работает правильно.

std может быть 0 только тогда, когда все элементы одинаковы, но в этом случае среднее равно элементам, и после вычитания вы получите все нули. Итак, второй np.where исправляет эту ситуацию.

person Soslan Tabuev    schedule 25.07.2019
comment
Кажется, это работает @Soslan! Позвольте мне провести некоторые проверки, и я вернусь, чтобы подтвердить. Спасибо! - person Eduardo G.R.; 26.07.2019
comment
Решение работает для вас, или есть другая проблема? - person Soslan Tabuev; 28.07.2019