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

Как перебирать строки в фрейме данных Pandas

Этот учебник объясняет, как перебирать строки в фрейме данных Pandas. Вы будете использовать функции items(), iterrows() и itertuples() и посмотрите на их производительность.

Автор оригинала: Ruslan Hasanov.

Вступление

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

В этом уроке мы рассмотрим, как перебирать строки в панде DataFrame .

Если вы новичок в Панд, вы можете прочитать наш учебник для начинающих . Как только вы освоитесь, давайте рассмотрим три основных способа итерации по фрейму данных:

  • предметы()
  • итерации()
  • итерации()

Итерация фреймов данных с элементами()

Давайте создадим Фрейм данных с некоторыми данными вымышленных людей:

import pandas as pd

df = pd.DataFrame({
    'first_name': ['John', 'Jane', 'Marry', 'Victoria', 'Gabriel', 'Layla'],
    'last_name': ['Smith', 'Doe', 'Jackson', 'Smith', 'Brown', 'Martinez'],
    'age': [34, 29, 37, 52, 26, 32]},
    index=['id001', 'id002', 'id003', 'id004', 'id005', 'id006'])

Обратите внимание, что мы используем id в качестве индекса DataFrame . Давайте посмотрим, как выглядит DataFrame :

print(df.to_string())
      first_name last_name  age
id001       John     Smith   34
id002       Jane       Doe   29
id003      Marry   Jackson   37
id004   Victoria     Smith   52
id005    Gabriel     Brown   26
id006      Layla  Martinez   32

Как перебирать этот Фрейм данных , мы будем использовать функцию items() :

df.items()

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


Мы можем использовать это для генерации пар cool_name и data . Эти пары будут содержать имя столбца и каждую строку данных для этого столбца. Давайте пройдемся по именам столбцов и их данным:

for col_name, data in df.items():
	print("col_name:",col_name, "\ndata:",data)

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

col_name: first_name
data: 
id001        John
id002        Jane
id003       Marry
id004    Victoria
id005     Gabriel
id006       Layla
Name: first_name, dtype: object
col_name: last_name
data: 
id001       Smith
id002         Doe
id003     Jackson
id004       Smith
id005       Brown
id006    Martinez
Name: last_name, dtype: object
col_name: age
data: 
id001    34
id002    29
id003    37
id004    52
id005    26
id006    32
Name: age, dtype: int64

Мы успешно перебрали все строки в каждом столбце. Обратите внимание, что столбец индекса остается неизменным на протяжении всей итерации, так как это связанный индекс для значений. Если вы не определяете индекс, то Панды будут перечислять столбец индекса соответствующим образом.

Мы также можем напечатать определенную строку с передачей индексного номера в data , как мы это делаем со списками Python:

for col_name, data in df.items():
	print("col_name:",col_name, "\ndata:",data[1])

Обратите внимание, что индекс списка индексируется нулем, поэтому data[1] будет ссылаться на вторую строку. Вы увидите этот вывод:

col_name: first_name 
data: Jane
col_name: last_name 
data: Doe
col_name: age 
data: 29

Мы также можем передать значение индекса в data .

for col_name, data in df.items():
	print("col_name:",col_name, "\ndata:",data['id002'])

Результат будет таким же, как и раньше:

col_name: first_name
data: Jane
col_name: last_name
data: Doe
col_name: age
data: 29

Итерация фреймов данных с помощью iterrows()

В то время как df.items() перебирает строки по столбцам, выполняя цикл для каждого столбца, мы можем использовать iterrows() для получения всех строковых данных индекса.

Давайте попробуем перебрать строки с помощью iterrows() :

for i, row in df.iterrows():
	print(f"Index: {i}")
	print(f"{row}\n")

В цикле for i представляет столбец индекса (или фрейм данных имеет индексы от id001 до id006 ), а row содержит данные для этого индекса во всех столбцах. Наш вывод будет выглядеть так:

Index: id001
first_name     John
last_name     Smith
age              34
Name: id001, dtype: object

Index: id002
first_name    Jane
last_name      Doe
age             29
Name: id002, dtype: object

Index: id003
first_name      Marry
last_name     Jackson
age                37
Name: id003, dtype: object

...

Аналогично, мы можем перебирать строки в определенном столбце. Просто передайте индексный номер или имя столбца в строку . Например, мы можем выборочно напечатать первый столбец строки следующим образом:

for i, row in df.iterrows():
	print(f"Index: {i}")
	print(f"{row['0']}")

Или:

for i, row in df.iterrows():
	print(f"Index: {i}")
	print(f"{row['first_name']}")

Они оба производят этот результат:

Index: id001
John
Index: id002
Jane
Index: id003
Marry
Index: id004
Victoria
Index: id005
Gabriel
Index: id006
Layla

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

Функция itertuples() также вернет генератор, который генерирует значения строк в кортежах. Давайте попробуем это:

for row in df.itertuples():
    print(row)

Вы увидите это в своей оболочке Python:

Pandas(Index='id001', first_name='John', last_name='Smith', age=34)
Pandas(Index='id002', first_name='Jane', last_name='Doe', age=29)
Pandas(Index='id003', first_name='Marry', last_name='Jackson', age=37)
Pandas(Index='id004', first_name='Victoria', last_name='Smith', age=52)
Pandas(Index='id005', first_name='Gabriel', last_name='Brown', age=26)
Pandas(Index='id006', first_name='Layla', last_name='Martinez', age=32)

Метод itertuples() имеет два аргумента: index и name .

Мы можем не отображать столбец индекса, установив параметр index в значение False :

for row in df.itertuples(index=False):
    print(row)

Наши кортежи больше не будут иметь отображаемого индекса:

Pandas(first_name='John', last_name='Smith', age=34)
Pandas(first_name='Jane', last_name='Doe', age=29)
Pandas(first_name='Marry', last_name='Jackson', age=37)
Pandas(first_name='Victoria', last_name='Smith', age=52)
Pandas(first_name='Gabriel', last_name='Brown', age=26)
Pandas(first_name='Layla', last_name='Martinez', age=32)

Как вы уже заметили, этот генератор выдает namedtuples с именем по умолчанию Pandas . Мы можем изменить это, передав аргумент People параметру name . Вы можете выбрать любое имя, которое вам нравится, но всегда лучше выбирать имена, соответствующие вашим данным:

for row in df.itertuples(index=False, name='People'):
    print(row)

Теперь наш выход будет:

People(first_name='John', last_name='Smith', age=34)
People(first_name='Jane', last_name='Doe', age=29)
People(first_name='Marry', last_name='Jackson', age=37)
People(first_name='Victoria', last_name='Smith', age=52)
People(first_name='Gabriel', last_name='Brown', age=26)
People(first_name='Layla', last_name='Martinez', age=32)

Производительность итераций с пандами

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

Для небольших наборов данных вы можете использовать метод to_string() для отображения всех данных. Для больших наборов данных, содержащих много столбцов и строк, вы можете использовать методы head(n) или tail(n) для печати первых n строк вашего фрейма данных (значение по умолчанию для n равно 5).

Сравнение скорости

Чтобы измерить скорость каждого конкретного метода, мы обернули их в функции, которые выполняли бы их в течение 1000 раз и возвращали среднее время выполнения.

Чтобы проверить эти методы, мы будем использовать обе функции print() и list.append () , чтобы обеспечить лучшие данные сравнения и охватить общие случаи использования. Чтобы определить справедливого победителя, мы будем перебирать фрейм данных и использовать только 1 значение для печати или добавления каждого цикла.

Вот как выглядят возвращаемые значения для каждого метода:

Например, while items() будет циклически циклировать столбец за столбцом:

('first_name', 
id001        John
id002        Jane
id003       Marry
id004    Victoria
id005     Gabriel
id006       Layla
Name: first_name, dtype: object)

iterrows() предоставит все данные столбца для конкретной строки:

('id001', 
first_name     John
last_name     Smith
age              34
Name: id001, dtype: object)

И, наконец, одна строка для itertuples() будет выглядеть следующим образом:

Pandas(Index='id001', first_name='John', last_name='Smith', age=34)

Вот средние результаты в секундах:

Метод Скорость (с) Тестовая Функция
предметы() 1.349279541666571 печатать()
итерации() 3.4104003086661883 печатать()
итерации() 0.41232967500279 печатать()
Метод Скорость (с) Тестовая Функция
предметы() 0.006637570998767235 добавлять()
итерации() 0.5749766406661365 добавлять()
итерации() 0.3058610513350383 добавлять()

Печать значений займет больше времени и ресурсов, чем добавление в целом, и наши примеры не являются исключением. В то время как itertuples() работает лучше в сочетании с print() , items() метод значительно превосходит другие при использовании для append() и iterrows() остается последним для каждого сравнения.

Обратите внимание, что результаты этих тестов сильно зависят от других факторов, таких как ОС, окружающая среда, вычислительные ресурсы и т. Д. Размер ваших данных также будет влиять на ваши результаты.

Вывод

Мы научились перебирать фрейм данных с помощью трех различных методов Панд – items() , iterrows() , itertuples() . В зависимости от ваших данных и предпочтений вы можете использовать один из них в своих проектах.