4 Сложные структуры данных в R
Если вдруг вас пугает это слово, то совершенно зря. Матрица (matrix) — это всего лишь “двумерный” вектор: вектор, у которого есть не только длина, но и ширина. Создать матрицу можно с помощью функции matrix() из вектора, указав при этом количество строк и столбцов.
Заметьте, значения вектора заполняются следующим образом: сначала заполняется первый столбик сверху вниз, потом второй сверху вниз и так до конца, т.е. заполнение значений матрицы идет в первую очередь по вертикали. Это довольно стандартный способ создания матриц, характерный не только для R.
Если мы знаем сколько значений в матрице и сколько мы хотим строк, то количество столбцов указывать необязательно:
Все остальное так же как и с векторами: внутри находится данные только одного типа. Поскольку матрица — это уже двумерный массив, то у него имеется два индекса. Эти два индекса разделяются запятыми.
Первый индекс — выбор строк, второй индекс — выбор колонок. Если же мы оставляем пустое поле вместо числа, то мы выбираем все строки/колонки в зависимости от того, оставили мы поле пустым до или после запятой:
Так же как и в случае с обычными векторами, часть матрицы можно переписать:
В принципе, это все, что нам нужно знать о матрицах. Матрицы используются в R довольно редко, особенно по сравнению, например, с MATLAB. Но вот индексировать матрицы хорошо бы уметь: это понадобится в работе с датафреймами.
То, что матрица — это просто двумерный вектор, не является метафорой: в R матрица — это по сути своей вектор с дополнительными атрибутами dim и (опционально) dimnames . Атрибуты — это свойства объектов, своего рода “метаданные.” Для всех объектов есть обязательные атрибуты типа и длины и могут быть любые необязательные атрибуты. Можно задавать свои атрибуты или удалять уже присвоенные: удаление атрибута dim у матрицы превратит ее в обычный вектор. Про атрибуты подробнее можно почитать здесь или на стр. 99-101 книги “R in a Nutshell” (Adler 2010) .
4.2 Массив
Два измерения — это не предел! Структура с одним типом данных внутри, но с тремя измерениями или больше, называется массивом (array). Создание массива очень похоже на создание матрицы: задаем вектор, из которого будет собран массив, и размерность массива.
4.3 Список
Теперь представим себе вектор без ограничения на одинаковые данные внутри. И получим список (list)!
А это значит, что там могут содержаться самые разные данные, в том числе и другие списки и векторы!
Если у нас сложный список, то есть очень классная функция, чтобы посмотреть, как он устроен, под названием str() :
Представьте, что список — это такое дерево с ветвистой структурой. А на конце этих ветвей — листья-векторы.
Как и в случае с векторами мы можем давать имена элементам списка:
К списку можно обращаться как с помощью индексов, так и по именам. Начнем с последнего:
А вот с индексами сложнее, и в этом очень легко запутаться. Давайте попробуем сделать так, как мы делали это раньше:
Мы, по сути, получили элемент списка — просто как часть списка, т.е. как список длиной один:
А вот чтобы добраться до самого элемента списка (и сделать с ним что-то хорошее), нам нужна не одна, а две квадратных скобочки:
Как и в случае с вектором, к элементу списка можно обращаться по имени.
Хотя последнее — практически то же самое, что и использование знака $.
Списки довольно часто используются в R, но реже, чем в Python. Со многими объектами в R, такими как результаты статистических тестов, удобно работать именно как со списками — к ним все вышеописанное применимо. Кроме того, некоторые данные мы изначально получаем в виде древообразной структуры — хочешь не хочешь, а придется работать с этим как со списком. Но обычно после этого стоит как можно скорее превратить список в датафрейм.
4.4 Датафрейм
Итак, мы перешли к самому главному. Самому-самому. Датафреймы (data.frames). Более того, сейчас станет понятно, зачем нам нужно было разбираться со всеми предыдущими темами.
Без векторов мы не смогли бы разобраться с матрицами и списками. А без последних мы не сможем понять, что такое датафрейм.
Вообще, очень похоже на список, не правда ли? Так и есть, датафрейм — это что-то вроде проименованного списка, каждый элемент которого является atomic вектором фиксированной длины. Скорее всего, вы представляли список “горизонтально.” Если это так, то теперь “переверните” список у себя в голове на 90 градусов. Так, чтобы названия векторов оказались сверху, а элементы списка стали столбцами. Поскольку длина всех этих векторов одинаковая (обязательное условие!), то данные представляют собой табличку, похожую на матрицу. Но в отличие от матрицы, разные столбцы могут иметь разные типы данных. В нашем случае первая колонка — character , вторая колонка — numeric , третья колонка — logical . Тем не менее, обращаться с датафреймом можно и как с проименованным списком, и как с матрицей:
Здесь мы сначала ивлекли колонку age с помощью оператора $ . Результатом этой операции является числовой вектор, из которого мы вытащили кусок, выбрав индексы 2 и 3 .
Используя оператор $ и присваивание можно создавать новые колонки датафрейма:
Ну а можно просто обращаться с помощью двух индексов через запятую, как мы это делали с матрицей:
Как и с матрицами, первый индекс означает строчки, а второй — столбцы.
А еще можно использовать названия колонок внутри квадратных скобок:
И здесь перед нами открываются невообразимые возможности! Узнаем, любят ли R те, кто моложе среднего возраста в группе:
Эту же задачу можно выполнить другими способами:
В большинстве случаев подходят сразу несколько способов — тем не менее, стоит овладеть ими всеми.
Датафреймы удобно просматривать в RStudio. Для это нужно написать команду View(df) или же просто нажать на названии нужной переменной из списка вверху справа (там где Environment). Тогда увидите табличку, очень похожую на Excel и тому подобные программы для работы с таблицами. Там же есть и всякие возможности для фильтрации, сортировки и поиска. 9
Но, конечно, интереснее все эти вещи делать руками, т.е. с помощью написания кода.
Все, что вы нажмете в этом окошке, никак не повлияет на исходную переменную. Так что можете смело использовать эти функции для исследования содержимого датафрейма.↩︎
В чем разница между data и data.frame в R?
Я знаю, что data.frame — это двумерная матрица со столбцами разных типов. Я думаю, что data — это еще один тип структуры данных в R , который может принимать несколько data.frame .
В RStudio теперь у меня два data : dcd и pdb :
Я пытался понять их свойства:
- dcd похож на матрицу из 101 строки и 19851 столбца?
- class(dcd) выводит «xyz» и «matrix» , означает ли это, что dcd принадлежит одновременно к типам «xyz» и «matrix» ?
- Как я могу создать data , например pdb , который включает несколько data.frame ?
например если бы у меня был
как я могу объединить students и teachers в data под названием people , чтобы я мог использовать people$students или people$teachers ?
возможно вам нужен list ? list(students = students, teachers = teachers)
Понятно, значит, data в RStudio означает что-нибудь еще, кроме values . dcd и pdb — это просто list ?
«данные» — это просто ярлык, который RStudio использует для определенных вещей в глобальной среде. Это не технический термин, такой как «матрица» или «фрейм данных» в R. «xyz», похоже, является настраиваемым классом, возможно, определенным в каком-то пакете, который вы используете, но о котором забыли упомянуть. В объектной системе R S3 «класс» — это просто атрибут, который используется в диспетчере методов.
Таким образом, dcd принадлежит как к типу xyz , так и к matrix , тогда как pdb принадлежит как к типу pdb , так и к типу sse . pdb тоже не list ?
Ответы 1
Если вы спрашиваете, как создать dataframe с именем people , чтобы вы могли получить доступ к именам людей, использующих people$students или people$teachers , то код для этого:
people будет кадром данных, который выглядит следующим образом:
Если вам нужен list , вы можете создать объект списка, подобный следующему:
И people2 будет списком:
Видите $ (знак доллара) рядом с каждым элементом в списке? Это говорит вам, как получить к ним доступ. Если вам нужен teachers.name , то print(people2$teachers.name) сделает это за вас.
Что касается других ваших вопросов:
- Похож ли dcd на матрицу со 101 строкой и 19851 столбцом?
Вы можете проверить размер матричного объекта, используя dim() , ncol() или nrow() . В вашем случае да, у него 101 строка и 19851 столбец.
- class(dcd) выводит «xyz» и «матрицу». Означает ли это, что dcd принадлежит одновременно к типам «xyz» и «матрица»?
Упрощенно, вы можете думать о нем как о наследовании класса matrix , а также класса xyz . Вы можете прочитать о классы и наследование в R.
- Как я могу создать такие данные, как pdb, которые включают несколько data.frame?
Посмотрите на мой код выше. people2 <- as.list(c(«students» = students, «teachers» = teachers)) создает list «множественных» фреймов данных.
так что pdb тоже не list ?
Для меня это определенно похоже на список, но у меня нет образца ваших данных. Рекомендую попробовать class(pdb) . list в R может содержать несколько объектов разных классов. Итак, ваш объект pdb может содержать фрейм данных, матрицу и т. д. Попробуйте class(pdb[[1]]) и class(pdb[[2]]) , и вы поймете, что я имею в виду.
Другой вопрос, а зачем использовать два слоя [] ? class(pdb[n]) всегда выдает «list» вместо n с любым номером.
Итак, pdb и sse — это классы, определенные автором пакета. Он наследует тип list , но всегда полезно прочитать документацию из пакета, чтобы быть уверенным. И то, что вы увидели, подтверждает то, что я сказал ранее: список может содержать несколько элементов, каждый из которых относится к разному классу. В вашем случае в вашем списке есть фрейм данных, матрица, логический вектор и вызов функции.
Матрицы в Python и массивы NumPy
Матрица — это двухмерная структура данных, в которой числа расположены в виде строк и столбцов. Например:
Эта матрица является матрицей три на четыре, потому что она состоит из 3 строк и 4 столбцов.
Матрицы в Python
Python не имеет встроенного типа данных для матриц. Но можно рассматривать список как матрицу. Например:
Этот список является матрицей на 2 строки и 3 столбца.
Обязательно ознакомьтесь с документацией по спискам Python , прежде чем продолжить читать эту статью.
Давайте посмотрим, как работать с вложенным списком.
Использование вложенных списков в качестве матрицы подходит для простых вычислительных задач. Но в Python есть более эффективный способ работы с матрицами – NumPy .
NumPy массивы в Python
NumPy — это расширение для научных вычислений, которое поддерживает мощный объект N-мерного массива. Прежде чем использовать NumPy, необходимо установить его. Для получения дополнительной информации,
- Ознакомьтесь: Как установить NumPy Python?
- Если вы работаете в Windows, скачайте и установите дистрибутив anaconda Python. Он поставляется вместе с NumPy и другими расширениями.
После установки NumPy можно импортировать и использовать его.
NumPy предоставляет собой многомерный массив чисел (который на самом деле является объектом). Давайте рассмотрим приведенный ниже пример:
Как видите, класс массива NumPy называется ndarray.
Как создать массив NumPy?
Существует несколько способов создания массивов NumPy.
Массив целых чисел, чисел с плавающей точкой и составных чисел
Когда вы запустите эту программу, результат будет следующий:
Массив нулей и единиц
Здесь мы указали dtype — 32 бита (4 байта). Следовательно, этот массив может принимать значения от -2 -31 до 2 -31 -1.
Использование arange() и shape()
Узнайте больше о других способах создания массива NumPy .
Операции с матрицами
Выше мы привели пример сложение, умножение матриц и транспонирование матрицы. Мы использовали вложенные списки, прежде чем создавать эти программы. Рассмотрим, как выполнить ту же задачу, используя массив NumPy.
Сложение двух матриц или сумма элементов массива Python
Мы используем оператор +, чтобы сложить соответствующие элементы двух матриц NumPy.
Умножение двух матриц Python
Чтобы умножить две матрицы, мы используем метод dot(). Узнайте больше о том, как работает numpy.dot .
Примечание: * используется для умножения массива (умножения соответствующих элементов двух массивов), а не умножения матрицы.
Транспонирование матрицы питон
Мы используем numpy.transpose для вычисления транспонирования матрицы.
Как видите, NumPy значительно упростил нашу задачу.
Доступ к элементам матрицы, строкам и столбца
Доступ к элементам матрицы
Также можно получить доступ к элементам матрицы, используя индекс. Начнем с одномерного массива NumPy.
Теперь выясним, как получить доступ к элементам двухмерного массива (который в основном представляет собой матрицу).
Доступ к строкам матрицы
Доступ к столбцам матрицы
Если вы не знаете, как работает приведенный выше код, прочтите раздел «Разделение матрицы».
Разделение матрицы
Разделение одномерного массива NumPy аналогично разделению списка. Рассмотрим пример:
Теперь посмотрим, как разделить матрицу.
Использование NumPy вместо вложенных списков значительно упрощает работу с матрицами. Мы рекомендуем детально изучить пакет NumPy, если вы планируете использовать Python для анализа данных.
Пожалуйста, оставьте свои мнения по текущей теме статьи. Мы очень благодарим вас за ваши комментарии, отклики, лайки, дизлайки, подписки!
Дайте знать, что вы думаете по этой теме статьи в комментариях. Мы очень благодарим вас за ваши комментарии, дизлайки, подписки, лайки, отклики!
Вадим Дворников автор-переводчик статьи « Python Matrices and NumPy Arrays »