Рубрики
Без рубрики

Python и Pandas: учебник DataFrame с примерами

В этой статье мы познакомимся с DataFrame из библиотеки Pandas и узнаем как они хранят информацию. Затем мы создадим их вручную и из файлов, а также рассмотрим способы манипуляции данными внутри них.

Автор оригинала: Olivera Popović.

Вступление

Pandas – библиотека Python с открытым исходным кодом для анализа данных. Она предназначена для эффективной и интуитивной обработки структурированных данных.

Двумя основными структурами данных в Pandas являются Series (Ряды) и DataFrame. Ряды являются по существу одномерными маркированными массивами любого типа данных, в то время как DataFrames являются двумерными, с потенциально гетерогенными типами данных, маркированными массивами любого типа данных. Гетерогенный означает, что не все «ряды» должны быть одинакового размера.

В этой статье мы рассматрим наиболее распространенные способы создания DataFrame и методы изменения их структуры.

Мы будем использовать блокнот Jupyter, так как он предлагает хорошее визуальное представление DataFrames. Однако любая среда IDE также выполнит эту работу, просто вызвав инструкцию print() для объекта DataFrame.

Создание DataFrame

Каждый раз, когда создается DataFrame, независимо от того, создается ли он вручную или создается из источника данных, например файла, данные должны упорядочиваться в табличном виде как последовательности строк с данными.

Это означает, что строки имеют одинаковый порядок полей, т.е. если требуется DataFrame с информацией об имени и возрасте человека, необходимо убедиться, что все строки содержат информацию одинаково.

Любое несоответствие приведет к тому, что DataFrame будет неисправен, что приведет к ошибкам.

Создание пустого DataFrame

Создать пустой DataFrame так же просто, как:

import pandas as pd
dataFrame1 = pd.DataFrame()

Рассмотрим, как можно добавлять строки и столбцы в этот пустой DataFrame при управлении их структурой.

Создание DataFrame из списков

Следуя принципу «последовательность строк с одинаковым порядком полей», можно создать DataFrame из списка, который содержит такую последовательность, или из нескольких списков объединённых вместе функцией zip() таким образом, что они обеспечивают последовательность так:

import pandas as pd

listPepper = [ 
    [50, "Bell pepper", "Not even spicy"], 
    [5000, "Espelette pepper", "Uncomfortable"], 
    [500000, "Chocolate habanero", "Practically ate pepper spray"]
]

dataFrame1 = pd.DataFrame(listPepper)

dataFrame1
# If you aren't using Jupyter, you'll have to call `print()`
# print(dataFrame1) 

Это приводит к:

результаты фрейма данных

Такого же эффекта можно было бы достичь, если бы данные находились в нескольких списках и были объединены вместе с помощью zip(). Этот подход может быть использован, когда данные, которые мы имеем, предоставляются в виде списков значений для одного столбца (поля), вместо вышеупомянутого способа, в котором список содержит данные для каждой конкретной строки.

Это означает, что у нас есть все данные (по порядку) для столбцов по отдельности, которые, будучи сжатыми вместе, создают строки.

Возможно, вы заметили, что метки столбцов и строк не очень информативны в созданном нами DataFrame. Можно передать эту информацию при создании DataFrame.

import pandas as pd

listScoville = [50, 5000, 500000]
listName = [
  "Bell pepper", "Espelette pepper", "Chocolate habanero"
]
listFeeling = [
  "Not even spicy", "Uncomfortable", "Practically ate pepper spray"
]
columns = ['Scoville', 'Name', 'Feeling']

dataFrame1 = pd.DataFrame(zip(listScoville, listName, listFeeling), columns=columns)

# Print the dataframe
dataFrame1

Что даёт нам тот же результат, что и раньше, только с более значимыми именами столбцов:

изменение имен столбцов во фрейме данных

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

listPepper = [
    { columnName1 : valueForRow1, columnName2: valueForRow1, ... },
    { columnName1 : valueForRow2, columnName2: valueForRow2, ... },
    ...
]

В нашем примере представление будет выглядеть следующим образом:

listPepper = [
  {'Scoville' : 50, 'Name' : 'Bell pepper', 'Feeling' : 'Not even spicy'},
  {'Scoville' : 5000, 'Name' : 'Espelette pepper', 'Feeling' : 'Uncomfortable'},
  {'Scoville' : 500000, 'Name' : 'Chocolate habanero', 'Feeling' : 'Practically ate pepper spray'},
]

И мы создадим DataFrame таким же образом, как и раньше:

dataFrame1 = pd.DataFrame(listPepper)

Создание DataFrame из словарей

Словари являются еще одним способом предоставления данных в виде столбцов. Каждому столбцу присваивается упорядоченный список строк значений.

dictionaryData = {
	'columnName1' : [valueForRow1, valueForRow2, valueForRow3...],
	'columnName2' : [valueForRow1, valueForRow2, valueForRow3...],
	....
}

Давайте представим те же данные, что и раньше, но в формате словаря:

import pandas as pd
dictionaryData = {
    'Scoville' : [50, 5000, 500000],
    'Name' : ["Bell pepper", "Espelette pepper", "Chocolate habanero"],
    'Feeling' : ["Not even spicy", "Uncomfortable", "Practically ate pepper spray"]
}

dataFrame1 = pd.DataFrame(dictionaryData)

# Print the dataframe
dataFrame1

Что дает нам ожидаемый результат:

создание фреймов данных из словарей

Чтение DataFrame из файла

Для чтения и записи DataFrames поддерживается множество типов файлов. Каждая функция соответствует типу файла, например read_csv(), read_excel(), read_json(), read_html() и т.д.

Наиболее распространенным типом файла является .csv (значения разделенные запятыми). Строки состоят из значений, разделенных специальным символом (чаще всего запятой). Можно задать другой разделитель с помощью аргумента sep.

Если вы не знакомы с типом файла .csv , вот пример того, как он выглядит:

Scoville, Name, Feeling
50, Bell pepper, Not even spicy 
5.000, Espelette pepper, Uncomfortable
10.000, Serrano pepper, I regret this
60.000, Bird's eye chili, 4th stage of grief 
500.000, Chocolate habanero, Practically ate pepper spray
2.000.000, Carolina Reaper, Actually ate pepper spray

Обратите внимание, что первой строкой в файле являются имена столбцов. Конечно, можно указать, с какой строки Pandas должен начать считывать данные, но по умолчанию Pandas рассматривает первую строку как имена столбцов и начинает загрузку данных из второй строки:

import pandas as pd

pepperDataFrame = pd.read_csv('pepper_example.csv')

# For other separators, provide the `sep` argument
# pepperDataFrame = pd.read_csv('pepper_example.csv', sep=';')

pepperDataFrame
#print(pepperDataFrame)

Что дает нам на выходе:

чтение файла в фрейм данных

Манипулирование Фреймами Данных

В этом разделе рассматриваются основные методы изменения структуры DataFrame. Однако прежде чем перейти к этой теме, необходимо знать, как получить доступ к отдельным строкам или группам строк, а также к столбцам.

Доступ/Расположение Элементов

Pandas имеет два разных способа выбора данных – loc[] и iloc[].

loc[] позволяет выбирать строки и столбцы с помощью меток, таких как row[‘Value’] и culumn[‘Other Value’]. В то же время, iloc[] принимает индекс записей, которые вы хотите выбрать, поэтому вы можете использовать только числа. Можно также выбрать столбцы, просто передав их имя в скобки. Посмотрим, как это работает в действии:

# Location by label
# Here, '5' is treated as the *label* of the index, not its value
print(pepperDataFrame.loc[5])
# Location by index
print(pepperDataFrame.iloc[1])

Выход:

Scoville               2.000.000
 Name                  Carolina Reaper
 Feeling               Actually ate pepper spray
Name: 5, dtype: object
Scoville               5.000
 Name                  Espelette pepper
 Feeling               Uncomfortable
Name: 1, dtype: object

Это также работает для группы строк, от 0 до n:

print(pepperDataFrame.loc[:1]) 

Это выводит:

питон панды loc

Важно отметить, что iloc[] всегда ожидает целое число. loc[] поддерживает и другие типы данных. Здесь мы также можем использовать целое число на ряду с другими типами данных, например строки.

Также можно получить доступ к определенным значениям для элементов. Например, может потребоваться получить доступ к элементу во 2-й строке, но вернуть только его значение Name:

print(pepperDataFrame.loc[2, 'Name'])

Это возвращает:

Chocolate habanero

Доступ к столбцам так же прост, как запись dataFrameName.ColumnName или dataFrameName [‘ColumnName’]. Второй вариант предпочтителен, так как столбец может иметь то же имя, что и зарезервированное имя в Pandas, и использование первого варианта в этом случае может вызвать ошибки:

print(pepperDataFrame['Name']) 
# Same output as print(pepperDataFrame.Name)

Это выводит:

0           Bell pepper
1      Espelette pepper
2    Chocolate habanero
Name: Name, dtype: object

Доступ к столбцам можно также получить с помощью loc[] и iloc[]. Например, мы получим доступ ко всем строкам, начиная с 0…n, где n – количество строк, и выберем первый столбец. Вывод совпадает с выводом предыдущей строки кода:

dataFrame1.iloc[:, 1] # or dataFrame1.loc[:, 'Name']

Манипулирование Индексами

Индексы – это метки строк в DataFrame и именно их мы используем при обращении к строкам. Поскольку мы не изменили индексы по умолчанию, которые Pandas присваивают DataFrame при создании, все наши строки были помечены целыми числами от 0 и выше.

Первый способ изменить индексацию вашего DataFrame – это использовать метод set_index() . Мы передаем любой из столбцов в вашем DataFrame этому методу, и он становится новым индексом. Таким образом, мы можем либо сами создавать индексы, либо просто назначить столбец в качестве индекса.

Обратите внимание, что метод не изменяет исходный DataFrame, а вместо этого возвращает новый DataFrame с новым индексом, поэтому мы должны назначить возвращаемое значение переменной DataFrame, если мы хотим сохранить изменение, или установить флаг inplace равным True:

import pandas as pd

listPepper = [
  {'Scoville' : 50, 'Name' : 'Bell pepper', 'Feeling' : 'Not even spicy'},
  {'Scoville' : 5000, 'Name' : 'Espelette pepper', 'Feeling' : 'Uncomfortable'},
  {'Scoville' : 500000, 'Name' : 'Chocolate habanero', 'Feeling' : 'Practically ate pepper spray'},
]

dataFrame1 = pd.DataFrame(listPepper)
dataFrame2 = dataFrame1.set_index('Scoville')

dataFrame2

Выход:

python pandas set index

Это будет работать так же хорошо:

dataFrame1 = pd.DataFrame(listPepper)
dataFrame1.set_index('Scoville', inplace=True)

dataFrame1

Теперь, когда у нас есть нестандартный индекс, мы можем использовать новый набор значений, используя reindex(), Pandas автоматически заполнит значения NaN для каждого индекса, который не может быть сопоставлен с существующей строкой:

new_index = [50, 5000, 'New value not present in the data frame']
dataFrame1.reindex(new_index)

Выход:

python pandas reindex

Вы можете контролировать, какое значение Pandas использует для заполнения пропущенных значений, установив необязательный параметр fill_value :

dataFrame1.reindex(new_index, fill_value=0)

Выход:

python pandas fill value

Поскольку мы установили новый индекс для нашего DataFrame, loc[] теперь работает с этим индексом:

dataFrame1.loc[5000] 
# dataFrame1.iloc[5000] outputs the same in this case

Это приводит к:

Name       Espelette pepper
Feeling       Uncomfortable
Name: 5000, dtype: object

Манипулирование строками (rows)

Добавление и удаление строк становится простым, если удобно использовать loc[]. Если задать несуществующую строку, она будет создана:

dataFrame1.loc[50] = [10000, 'Serrano pepper', 'I regret this']
dataFrame1

Выход:

python pandas loc output

И если вы хотите удалить строку, вы указываете ее индекс функции drop () . Он принимает необязательный параметр axis . Ось | принимает 0 / индекс или 1 / колонки . В зависимости от этого функция drop() отбрасывает либо вызываемую строку, либо вызываемый столбец.

Если требуется удалить строку, необходимо указать ее индекс для функции drop(). Она принимает необязательный параметр, axis. Axis может быть 0/index или 1/columns. В зависимости от этого функция drop() удаляет строку или столбец для которого она была вызвана.

Если не указать значение параметра axis , то соответствующая строка будет удалена по умолчанию, так как axis 0 по умолчанию:

Если не указать значение параметра axis, соответствующая строка будет удалена по умолчанию, так как axis по умолчанию равен 0:

dataFrame1.drop(1, inplace=True) 
# Same as dataFrame1.drop(1, axis=0)

Выход:

python pandas drop function

Вы также можете переименовать строки, которые уже существуют в таблице. Функция rename() принимает словарь изменений, которые вы хотите внести:

dataFrame1.rename({0:"First", 1:"Second"}, inplace=True)

Выход:

питон панды переименовать

Обратите внимание, что drop() и rename() также принимают необязательный параметр inplace . Установка этого параметра в True ( False по умолчанию) скажет Pandas изменить исходный DataFrame вместо того, чтобы возвращать новый. Если оставить его не заданным, вам придется упаковать полученный DataFrame в новый, чтобы сохранить изменения.

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

dataFrame1.loc[3] = [60.000, "Bird's eye chili", "4th stage of grief"]
dataFrame1.loc[4] = [60.000, "Bird's eye chili", "4th stage of grief"]

dataFrame1

Что дает нам выход:

python панды добавить дубликат

Теперь мы можем вызвать drop_duplicates() :

dataFrame1.drop_duplicates(inplace=True)

dataFrame1

И дубликаты строк будут удалены:

python pandas удалить дубликат

Манипулирование столбцами (columns)

Новые столбцы можно добавлять аналогично добавлению строк:

dataFrame1['Color'] = ['Green', 'Bright Red', 'Brown']
dataFrame1

Выход:

панды python манипулируют столбцами

Также, как и строки, столбцы можно удалить, вызвав функцию drop() , с той лишь разницей, что вы должны установить необязательный параметр axis в значение 1 чтобы Pandas знали, что вы хотите удалить столбец, а не строку:

dataFrame1.drop('Feeling', axis=1, inplace=True)

Выход:

панды питона падают на место

Когда речь идет о переименовании столбцов, функции rename() нужно сказать конкретно, что мы хотим изменить столбцы, установив необязательные параметр columns значение нашего “словаря изменений”:

dataFrame1.rename(columns={"Feeling":"Measure of Pain"}, inplace=True)

Выход:

python pandas переименовать столбец

Опять же, как и при удалении/переименовании строк, вы можете установить необязательный параметр на месте в True если вы хотите, чтобы исходный DataFrame был изменен вместо функции, возвращающей новый DataFrame .

Опять же, как и при удалении/переименовании строк, можно установить для параметра inplace значение True, если требуется изменить исходный DataFrame вместо создания нового DataFrame.

Вывод

В этой статье мы рассмотрели, что такое Pandas DataFrame s, поскольку они являются ключевым классом из фреймворка Pandas, используемого для хранения данных.

В этой статье мы рассмотрели, что такое Pandas DataFrame, поскольку он является ключевым классом фреймворка Pandas для хранения данных.

Мы научились создавать DataFrame вручную, используя список и словарь, после чего считывали данные из файла.

Затем мы манипулировали данными в DataFrame – используя loc[] и iloc[] , мы находили данные, создавали новые строки и столбцы, переименовывали существующие и затем удаляли их.

Затем мы манипулировали данными в DataFrame используя loc[] и iloc[]. Мы обнаружили данные, создали новые строки и столбцы, переименовали существующие, а затем удалили их.