#python #math #numpy #fft
#python #математика #numpy #fft
Вопрос:
У меня возникли проблемы с выполнением 2D быстрых преобразований Фурье в 3D массиве. Они имеют математическую природу и характер «понимания python / numpy».
РЕДАКТИРОВАТЬ: Для пояснения, основные вопросы: как numpy.fft справляется с массивами с маской? Могу ли я усреднить по оси, а затем выполнить БПФ и получить тот же результат, что и при выполнении БПФ, а затем усреднить по осям, которые не были задействованы в БПФ?
Массив состоит из значения потока двуокиси углерода (в «единицах») между атмосферой и океаном для каждого градуса широты и долготы (в определенной области). Форма массива (730, 50, 182) соответствует (времени, широте, долготе). Значения land маскируются с помощью:
import numpy as np
from numpy import ma
carbon_flux = ma.masked_values(carbon_flux, 1e 20)
Я хотел бы показать логарифм дисперсии 2D преобразования Фурье carbon_flux, усредненной по долготе. Я усредняю массив по последней оси (долгота), а затем выполняю преобразование Фурье следующим образом:
ft_type_1 = np.log(np.abs(np.fft.fft2(ma.mean(cflux, 2)))
Это дает мне приемлемый результат. Однако мне сказали сначала выполнить усреднение:
ft_type_2 = np.log(np.mean(np.abs(np.fft.fft2(carbon_flux, axes=(0, 1))),axis=2)
Это приводит к тому, что маскированные значения используются для вычисления fft (я могу судить по первому значению fft порядка 10e19).
Насколько я понимаю, результат выполнения усреднения до fft будет отличаться от выполнения усреднения после fft. Прав ли я в предположении или не имеет значения, в каком порядке я выполняю эти функции?
Использует ли fft замаскированные значения? Могу ли я избежать этого?
Наконец, я вычислил логарифм 2D преобразования Фурье carbon_flux, усредненный по широте. Я не понимаю, как вычислить логарифм ДИСПЕРСИИ 2D преобразования Фурье, усредненного по широте. Нужно ли просто возводить значение моего результирующего изображения fft в квадрат, чтобы получить дисперсию?
Похоже, это очень сложная серия вопросов, но мы будем признательны за любую помощь в любом отделе. Спасибо.
Комментарии:
1. Во-первых, я не знаю, как numpy.fft справляется со всем этим. Однако FT является линейной операцией, поэтому, пока вы усредняете данные перед получением абсолютного значения, это не должно иметь большого значения.
2. @aganders3 Спасибо. Да, похоже, это верно на практике. Две результирующие цифры почти точно совпадают. Интересно, откуда берутся небольшие различия?
Ответ №1:
После краткого просмотра документации, я думаю, numpy.fft
можно просто проигнорировать маску. Я бы попробовал использовать ma.filled()
функцию, чтобы поместить какое-то другое значение во все замаскированные записи.
Что-то вроде этого (взято из вашего примера кода):
ft_type_1 = np.log(np.abs(np.fft.fft2(ma.mean(carbon_flux.filled(cflux_fill_value), 2)))
ft_type_2 = np.log(np.mean(np.abs(np.fft.fft2(carbon_flux.filled(cflux_fill_value), axes=(0, 1))),axis=2)
где cflux_fill_value
есть какое-то разумное предположение, чтобы заменить замаскированные значения. Значение заполнения также можно задать на другом шаге (оно сохраняется как часть массива с маской), и тогда вы могли бы использовать carbon_flux.filled()
без аргумента.
Комментарии:
1. Под игнорированием, я полагаю, вы имеете в виду numpy. fft использует то, чем массив был до того, как он был замаскирован. Я заменил замаскированные значения carbon_flux на среднее значение:
carbon_flux_data = ma.getdata(carbon_flux)
тогдаi= np.where(carbon_flux_data > 1e19)
, тогдаcarbon_flux_data[i] = ma.mean(carbon_flux)
. Даст ли это более точное значение для ft_type_1[0, 0], члена нулевой частоты (среднее значение сигнала)?2. Короткий ответ: да, вероятно. Я не знаком с вашими данными, но, похоже, они были собраны с помощью некоторых датчиков, которые вышли из строя при нескольких измерениях, выдавая значения> 1e9. Правильно ли это? Поскольку вы не знаете там значений, вы должны угадать — замена на среднее значение является одним из вариантов, и может быть хорошим предположением. Другим вариантом было бы угадать эти точки на основе измерений из близлежащих времен / местоположений. Вы, вероятно, знаете больше о данных, поэтому я бы оставил вам, как лучше заполнить пробелы. Это может не иметь большого значения, в зависимости от того, сколько значений «отсутствует».
3. Кроме того, повторите: первую часть вашего поста. Я думаю,
numpy.fft
используется то, чем был массив до того, как он был замаскирован. Я думаю, что использованиеcarbon_flux.filled(ma.mean(carbon_flux))
должно выполнять то же самое, что вы описали. Я предложил заполнение нулями, потому что это распространено в моей области (MRI), но, вероятно, не лучшая идея для вашего случая!4. Спасибо! Замаскированные данные представляют значения суши, поскольку на суше нет газообмена воздух-море.