В двух предыдущих блокнотах мы изучили некоторые из основных принципов программирования на Python, которые должны дать вам инструменты для создания и использования более сложного кода, который можно использовать для решения проблем и ускорения существующего рабочего процесса.
Python - это язык с открытым исходным кодом, поскольку для него работают разработчики со всего мира и из нескольких организаций. Кроме того, существует множество различных внешних сторонних модулей, которые расширяют и улучшают существующие функциональные возможности Python.
SНекоторые из этих модулей представляют собой огромные, стабильные разработки и могут использоваться во всевозможных различных сценариях использования, в то время как другие гораздо более специфичны для одной области. В этой записной книжке мы рассмотрим несколько наиболее полезных модулей, которые требуются для многих конкретных задач ГИС, которые мы рассмотрим в последующих блокнотах.
В этом уроке мы поговорим о трех основных модулях:
Они должны предоставить вам большинство инструментов для доступа и использования куба данных, а также для выполнения других операций ГИС позже. Также используются некоторые другие модули, которые не будут рассматриваться так подробно, но они будут перечислены со ссылками на их веб-сайты в конце этой записной книжки, которые вы можете просмотреть, если хотите.
Сначала пару слов о модулях. Модули можно импортировать в верхнюю часть скриптов и блокнотов, таких как этот, что затем позволяет использовать содержащиеся в них функции в коде. Фактически, импорт модуля ссылается на этот модуль в вашем коде, поэтому любые функции или методы внутри модуля могут использоваться вашим кодом.
Существует ряд различных соглашений, используемых для импорта модулей. Например, скажем, у вас есть модуль под названием 'pymodule'. Самый простой способ импортировать этот модуль - просто написать:
import pymodule
вверху вашего скрипта или блокнота. Затем функцию в этом модуле можно было бы вызвать аналогично методам списка, которые мы рассматривали ранее. Некоторые модули имеют хорошо известные сокращения для импорта, которые используются при их импорте, снова используя пример pymodule, мы бы написали:
import pymodule as pym
.
Кроме того, можно вызывать отдельные подмодули или функции из более крупного модуля. Иногда может быть полезно вызвать подмодуль для скорости, поскольку это означает, что нужно импортировать только часть большего модуля. Не рекомендуется импортировать только одну функцию из модуля, так как интерпретатору Python все равно нужно сканировать весь модуль на предмет функции и он жестко кодирует этот модуль в ваш скрипт / записную книжку. В приведенном ниже коде мы импортируем все модули, необходимые для выполнения приведенного ниже кода:
import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
Numpy (сокращение от Numerical Python) - один из самых полезных модулей для любого вида анализа данных в Python. Он имеет набор встроенных математических функций, от тривиальных, таких как np.sqrt
(используется для вычисления квадратных корней) и np.mean
(используется для вычисления среднего), до сложных функций линейной алгебры, используемых для преобразований матриц.
Кроме того, он расширяет и улучшает существующие структуры списков Python, вводя массивы numpy, которые могут быть 1, 2 или n-мерными массивами. Это полезные структуры данных для запроса и обработки данных, но они построены на других модулях, таких как xarray (который мы рассмотрим позже) и pandas pandas.
И, наконец, многие другие модули построены на основе структуры массива данных, которую использует Numpy, из-за его скорости и простоты использования, поэтому знакомство с Numpy является важным и полезным навыком, который нужно развивать при программировании на Python.
WМы начнем с рассмотрения основных массивов Numpy. Эти массивы содержат немного больше метаданных, чем встроенные списки Python, и ими также легче манипулировать, особенно для математических вычислений. Они могут быть инициализированы как пустые массивы или, во многих случаях, являются результатом преобразования списка Python. Запустите поле кода ниже, чтобы увидеть примеры способов запуска массивов Numpy:
zeros_array = np.zeros(10)
ones_array = np.ones(10)
print('Array of zeros:',zeros_array)
print('Array of ones:',ones_array)
normal_list = [1.0,1.0,1.0,1.0,1.0,1.0]
numpy_list = np.array(normal_list)
print('List converted to numpy array:',numpy_list)
Выше было несколько примеров различных способов создания одномерных (1D) массивов Numpy. Можно инициировать список требуемого размера и формы, еще не заполняя его фактическими значениями данных, используя либо функцию np.zeros()
, либо функцию np.ones()
для создания массива Numpy, состоящего только из числа ноль или один соответственно.
Кроме того, можно преобразовать обычный список в массив Numpy в тех случаях, когда у вас уже есть обычный список Python, но вам нужно выполнить некоторые вычисления, которые могут быть лучше обработаны с помощью Numpy. В этом случае использование функции np.array()
преобразует этот список в массив Numpy.
Наиболее полезными примерами использования массивов Numpy являются их использование как двумерные (2D) массивы. Эти массивы также могут быть инициализированы очень похожими способами, что можно показать, выполнив приведенный ниже код:
zeros_ndarray = np.zeros([3,2])
ones_ndarray = np.ones([3,2])
print('2D Array of zeros:',zeros_ndarray)
print('2D Array of ones:',ones_ndarray)
normal_list = [[1.0,1.0],[2.0,2.0],[3.0,3.0]]
numpy_ndlist = np.array(normal_list)
print('List converted to 2D numpy array:',numpy_ndlist)
В приведенном выше разделе кода все ранее определенные массивы можно было переопределить как 2D-массивы Numpy, с числами в квадратных скобках, обозначающими форму массивов (фактически, можно было бы определить 1D-массив таким образом, используя, например, np.ones([1,10])
, но на практике проще просто записать количество значений.
Существует широкий спектр применений массивов Numpy, и их можно использовать для ускорения практически любой числовой задачи в Python, но писать гораздо больше об использовании массивов Numpy в этом руководстве было бы очень долго. Другие варианты использования появятся в более поздних уроках этой серии, поэтому вы увидите там более продвинутое использование Numpy. Между тем, на веб-сайте Numpy есть много документации по многим функциям, если вы хотите узнать больше, для чего они могут использоваться.
Matplotlib - это основная библиотека построения графиков в Python, позволяющая использовать широкий спектр типов и стилей графиков. Он имеет узнаваемые и простые в использовании функции построения графиков, но есть вспомогательные функции, которые позволяют при необходимости настраивать графики.
В этом руководстве мы рассмотрим несколько различных типов графиков с графиками для построения линейных графиков, графиками рассеяния и графиками типа двумерной гистограммы (которые часто используются для многих графиков спутниковых данных и данных ГИС).
Давайте сделаем очень простой линейный график с помощью matplotlib. Скажем, мы хотим нарисовать линию $x = y$, нам нужно создать списки или массивы, соответствующие значениям x и y в нескольких точках вдоль линии, прежде чем указать matplotlib построить эти значения и, наконец, отобразить (или в некоторых случаях сохранить) график. Запустите приведенный ниже код, чтобы построить этот график.
x = [1.0,2.0,3.0,4.0,5.0]
y = [1.0,2.0,3.0,4.0,5.0]
plt.plot(x,y)
Это очень простой график, и есть ряд «аргументов ключевого слова» (также известных как kwargs), которые можно указать после указания x и y в аргументах графика, таких как стиль линии, размер, цвет и т.д. дополнительные аргументы можно указать с помощью plt.
после создания графика, например, добавление заголовков, заголовков осей, меток, меток, логарифмических осей и многих других. Также можно использовать plt.plot
tдля изменения графика с линейного на точечный график, указав, что аргументы ключевого слова "маркер" равны '.'. Попробуйте это в поле ниже, скопировав последнюю строку из предыдущего примера, но добавив в kwarg, marker='.'
x = [1.0,2.0,3.0,4.0,5.0]
y = [1.0,2.0,3.0,4.0,5.0]
plt.plot(x,y, marker='.')
Хотя использование plt.plot()
может быть жизнеспособным способом построения диаграмм рассеяния, специальная функция plt.scatter()
имеет для этого гораздо больше возможностей. Однако с базовой точки зрения построение диаграммы рассеяния почти идентично plt.plot()
, просто заменяя слово plot на scatter, как например:
plt.scatter(x, y)
Также возможно построить два разных типа графиков друг над другом. Это делается простым вызовом двух функций plt
одну за другой. На приведенном ниже графике попробуйте построить два графика друг над другом, сначала вызывая plt.plot()
с x и y в качестве аргументов, как указано выше, а затем вызывая plt.scatter()
с x_scat и y_scat.
x_scat = [2.0,4.0,4.0,2.0]
y_scat = [1.0,1.0,4.5,4.5]
plt.plot(x, y)
plt.scatter(x_scat, y_scat)
x_scat = [2.0,4.0,4.0,2.0]
y_scat = [1.0,1.0,4.5,4.5]
Надеюсь, вам удалось провести прямую линию, обозначающую $x=y$ и прямоугольник между 2,0 и 4,0 по оси x и от 1,0 до 4,5 по оси y.
Последний тип графика, который мы рассмотрим в этом уроке, - это plt.imshow()
, который предназначен для построения двухмерных наборов данных и поэтому действительно очень полезен для построения спутниковых или пространственных данных. Чтобы что-то построить, нам сначала понадобится многомерный массив, из которого проще всего сделать массив из numpy. Приведенный ниже код позволяет создать многомерный массив numpy с помощью функции Numpy randint, которая создает массив случайных чисел от 0 до указанного значения в форме, определяемой параметром size (в данном случае матрица 6x6). Затем это можно построить с помощью plt.imshow()
.
implot = np.random.randint(5,size=[6,6])
plt.imshow(implot)
Проверьте свое понимание процессов, которые мы описали в этом уроке, построив график рассеяния по графику imshow, убедившись, что массивы x_scat
и y_scat
вызываются в качестве аргументов для plt.scatter()
, а массив implot
в качестве аргумента для функции plt.imshow()
function.
plt.imshow(implot)
plt.scatter(x_scat, y_scat)
Xarray расширяет функциональность массивов Numpy за счет дополнительных метаданных и возможностей, что делает их идеальной структурой данных для работы со спутниковыми данными в Python. У них также есть встроенная возможность создавать графики, такие как plt.imshow()
, показанные выше.
С помощью Xarray также проще обрабатывать многомерные данные, например, содержащие несколько массивов за разные дни или данные с нескольких спутниковых диапазонов. В результате намного проще анализировать спутниковые данные в структуре Xarray, и любые запросы к кубу данных возвращают Xarrays, поэтому это предпочтительный метод взаимодействия с кубом данных.
Давайте сначала создадим Xarray. Xarray имеет две основные структуры данных - DataArrays и Datasets. DataArrays - это фактически массивы Numpy с дополнительной информацией, которую необходимо определить при создании, в то время как Datasets содержат несколько DataArrays и, как таковые, могут содержать несколько переменных в одном наборе данных. Чтобы использовать встроенную функцию построения графиков, необходимо преобразовать набор данных в массив данных или выбрать массив данных, скрытый в общем наборе данных. Ниже приведен пример того, как создать DataArray из Xarray:
data_vals = np.random.randint(5,size=[3,4,4])
x = [0,1,2,3]
y = [0,1,2,3]
time = ['20190101','20190102','20190103']
test_array = xr.DataArray(data_vals,coords=[time,x,y],dims=['time','x','y'])
print(test_array)
Здесь происходит довольно много всего, поэтому давайте немного разберемся.
Прежде всего, Numpy 3D-массив был создан с использованием np.random.randint()
, как было показано ранее в примерах matplotlib. Итак, у нас есть массив Numpy, содержащий три матрицы 4x4. Чтобы создать из него Xarray, необходимо указать координаты для каждой из трех осей. В этом примере каждый массив 4x4 представляет собой пространственный массив в направлениях x и y, причем каждый массив относится к разному времени. Это тип Xarray, который будет возвращать куб данных.
Кроме того, необходимо определить 'затемнения', которые являются метками для каждой из координат и представляют собой список строк, определяющих каждый тип координат.
DataArrays легко преобразовать в наборы данных и наоборот, используя команды to_dataset()
и to_array()
. Например, test_array можно преобразовать в набор данных как переменную в наборе данных с помощью команды в поле ниже:
test_dataset = test_array.to_dataset(name='test_array')
print(test_dataset)
Вышеупомянутый набор данных является в точности форматом данных из куба данных. Получение данных из куба данных выполняется немного другим способом, который будет рассмотрен в следующей записной книжке. Однако полезно увидеть, откуда берутся эти структуры данных и как они построены.
Теперь, когда мы создали DataArray и Dataset, мы посмотрим, как можно управлять этими структурами данных. Например, как мы на самом деле смотрим на массивы Numpy под набором данных, чтобы использовать функции Numpy?
В приведенном ниже коде показан пример этого:
test_dataset['test_array'].values
В этом случае мы выбрали переменную test_array
, используя квадратные скобки и ее имя в виде строки, чтобы получить только data_array. Однако это будет полный массив DataArray с дополнительными координатами и размерами, как мы видели, когда мы его определили. Чтобы получить только значения данных из массива, важно использовать метод .values
для получения массива Numpy.
С этого момента мы можем использовать функции Numpy для выполнения преобразований в массиве. Однако это не всегда необходимо для простых функций, таких как среднее и медиана, которые могут выполняться прямо в структурах данных Xarray, поскольку в них встроена некоторая функциональность Numpy.
В приведенном ниже примере мы нашли медианное значение набора данных test_array. Запустите код, чтобы увидеть эту функциональность:
test_dataset.median()
Вы также можете использовать оператор print
, чтобы показать результаты другим способом.
print(test_dataset.median())
Попробуйте сами. В пустом поле ниже найдите среднее значение набора данных. Метод точно такой же, за исключением того, что вы ищете среднее вместо медианы.
test_dataset.mean()
Наконец, мы рассмотрим использование Xarray для построения данных, используя встроенные возможности Matplotlib, которые использует Xarray. Возвращаясь к нашему набору данных Xarray test_dataset
, чтобы отобразить этот аспект, мы должны сделать несколько отдельных вещей.
Если мы не рисуем изображение RGB, функция Xarray plot будет работать только в том случае, если для построения графика указан 2D-массив. Кроме того, можно построить только DataArray, но не Dataset, поскольку DataArray содержит только одну переменную. Затем, чтобы построить аспект test_dataset
, мы должны сначала сохранить его как DataArray, а затем выбрать только одну из матриц 4x4 (представляющих время в этом примере), которая может быть построена как 2D-изображение. Эта функция показана ниже:
plot_image = test_dataset['test_array']
plot_image = plot_image.isel(time=0)
plot_image.plot()
plt.show()
Итак, мы успешно построили первую матрицу 4x4, выбрав только ее с помощью команды .isel(time=0)
. Сам график возникает при вызове метода .plot()
. Это простейшая форма, и для улучшения сюжета можно указать несколько кваргов. Наконец, график был отображен с помощью plt.show()
.