Существуют ли различия в производительности/рекомендуется ли использовать атрибуты фрейма данных pandas при ссылке на столбцы?

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

Мне интересно, какой формат считается «наилучшей практикой», и есть ли какие-либо различия в производительности между ними (или это может потенциально варьироваться в зависимости от обстоятельств?). Я не нахожу много ресурсов по этому вопросу.

Вот упрощенный пример того, что я имею в виду: создание столбца «зеленый» со строками, имеющими значение «Истина», если столбцы «синий» и «желтый» имеют значение «Истина», в противном случае строки являются ложными.

# using brackets.
df['green'] = np.where((df['blue']==True) & (df['yellow']==True), True, False)

против.

# using periods.
df['green'] = np.where((df.blue==True) & (df.yellow == True), True, False)

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

  • Есть ли разница в производительности при использовании любого формата?
  • Какой формат считается лучшей практикой?

Самая распространенная проблема, которую я видел здесь: рассмотрим фрейм данных df со столбцами df['name'] и df['shape']. Сохранение 4 символов ввода приведет к тому, что В самом деле испортит вас, когда вы начнете устанавливать/изменять атрибут name фрейма данных вместо внесения изменений в столбец 'name' или выдавать ошибки при попытке изменить поведение df.shape по умолчанию. IMO всегда всегда используйте скобки для доступа к столбцу

G. Anderson 22.03.2022 23:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
30
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Между двумя нотациями нет разницы в производительности:

  • df.blue использует __getattr__ для поиска в правом столбце
  • df['blue'] использует __getitem__ для поиска нужного столбца (или индекса)

У вас должен быть действительный идентификатор Python, если вы хотите использовать первую форму, и вы не можете использовать имя столбца, такое как shape, size, values и так далее.

Вторая форма более явная и используется LocIndexer. Это позволяет вам использовать имя столбца, например 2022 или Energy (KWH). Я явно предпочитаю это обозначение.

Если производительность имеет значение, не используйте where или аналогичную дорогостоящую функцию. Классическая маска подойдет. Использование timeit может дать вам представление о затратах времени:

import pandas as pd
import numpy as np
n = 100
df = pd.DataFrame({'yellow' : np.random.randint(0, 2, n),
                   'blue' : np.random.randint(0, 2, n)}, dtype = np.bool8)

%timeit np.where((df['blue']==True) & (df['yellow']==True), True, False)
252 µs ± 17.3 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

%timeit np.where((df.blue==True) & (df.yellow == True), True, False)
245 µs ± 3.06 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

%timeit df['blue'] & df['yellow']
72.1 µs ± 4.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

%timeit df.blue & df.yellow
77.1 µs ± 1.75 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

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

Что касается синтаксиса, я предпочитаю использовать .loc или .iloc для доступа к элементам, так как я нахожу его более «пандовым», но это полностью на ваше усмотрение.

Другие вопросы по теме