Субсетирование датафрейма по подсетке датафрейма и по серии

Вопрос или проблема

Я изучаю Data Science на Datacamp, и у меня возник вопрос: если у нас есть DataFrame cars, структурированный следующим образом

     cars_per_cap        country  drives_right
US            809  United States          True
AUS           731      Australia         False
JPN           588          Japan         False
IN             18          India         False
RU            200         Russia          True
MOR            70        Morocco          True
EG             45          Egypt          True

то я могу отфильтровать только автомобили, у которых drives_right = True, введя print(cars[cars['drives_right']]). Это вернет следующее:

     cars_per_cap        country  drives_right
US            809  United States          True
RU            200         Russia          True
MOR            70        Morocco          True
EG             45          Egypt          True

и это потому, что cars['drives_right'] является серией. Мне стало интересно, что произойдет, если я вместо этого использую DataFrame cars[['drives_right']], и я получил следующее:

     cars_per_cap country drives_right
US            NaN     NaN         True
AUS           NaN     NaN          NaN
JPN           NaN     NaN          NaN
IN            NaN     NaN          NaN
RU            NaN     NaN         True
MOR           NaN     NaN         True
EG            NaN     NaN         True

кто-нибудь из вас знает, почему это происходит?

Позвольте мне объяснить это через следующее

import pandas as pd
data = [{'cars_per_cap': 89, 'country': 'United States', 'drives_right': True },{'cars_per_cap': 289, 'country': 'Australia', 'drives_right': False },{'cars_per_cap': 189, 'country': 'Japan', 'drives_right': False } ]
cars =pd.DataFrame(data, index=["US", "AUS", "JPN"])
print (cars)

вывод :

     cars_per_cap        country  drives_right
US             89  United States          True
AUS           289      Australia         False
JPN           189          Japan         False

Вы можете видеть, что индексы, созданные здесь, – это ‘US’, ‘AUS’, ‘JPN’

#С тремя индексами столбцов, последние значения такие же, как ключи словаря, остальные - нет
df1 = pd.DataFrame(data, index=['US', 'AUS', 'JPN'], columns=['a', 'b', 'drives_right'])
print (df1)

вывод :

      a   b  drives_right
US  NaN NaN          True
AUS NaN NaN         False
JPN NaN NaN         False

Пожалуйста, смотрите, DataFrame df1 создан с некоторыми индексами столбцов, отличными от ключа словаря; таким образом, NaN были добавлены вместо значений.

Та же причина, когда вы используете :

print(cars[cars['drives_right']])

  cars_per_cap        country  drives_right
US            89  United States          True

когда вы используете :

print (cars[cars[['drives_right']]])

     cars_per_cap country drives_right
US            NaN     NaN         True
AUS           NaN     NaN          NaN
JPN           NaN     NaN          NaN

Ответ или решение

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

1. Основные конструкции pandas

Для начала рассмотрим структуру DataFrame cars:

import pandas as pd

data = [
    {'cars_per_cap': 89, 'country': 'United States', 'drives_right': True},
    {'cars_per_cap': 289, 'country': 'Australia', 'drives_right': False},
    {'cars_per_cap': 189, 'country': 'Japan', 'drives_right': False}
]
cars = pd.DataFrame(data, index=['US', 'AUS', 'JPN'])

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

2. Фильтрация по условию

Чтобы извлечь только те строки, где значение drives_right равно True, мы можем воспользоваться следующим синтаксисом:

print(cars[cars['drives_right']])

Результат:

     cars_per_cap        country  drives_right
US             89  United States          True

Здесь мы видим, что cars['drives_right'] возвращает Серию (Series), которая является одномерным массивом. При использовании этой серии для фильтрации DataFrame, pandas понимает, что нужно извлечь строки, соответствующие условию.

3. Фильтрация с использованием под DataFrame

Теперь давайте попробуем фильтровать данные с использованием под DataFrame:

print(cars[cars[['drives_right']]])

Результат:

     cars_per_cap country drives_right
US            NaN     NaN         True
AUS           NaN     NaN        False
JPN           NaN     NaN        False

В этом случае cars[['drives_right']] возвращает DataFrame с одной колонкой. Когда мы используем этот DataFrame для фильтрации cars, происходит следующее:

  • pandas пытается сопоставить все индексы из cars[['drives_right']] с индексами основного DataFrame cars.
  • Поскольку фильтрация требует булевой маски (True/False значения), в результате мы получаем NaN для всех строк, где соответствующие индексы не совпадают.

4. Пояснение причины

Причина, по которой в случае использования DataFrame происходит вывод NaN, касается механизма работы pandas с индексами:

  • Серия (Series) автоматически сопоставляется с индексами DataFrame, и при этом распознает истинные значения как соответствующие строкам для извлечения.

  • DataFrame (например, cars[['drives_right']]) возвращает не одну булевую маску, а целую таблицу, что требует дополнительной обработки для фильтрации. Вместо этого, когда индекс не совпадает для строки, pandas просто заполняет значения NaN.

Заключение

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

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

Оцените материал
Добавить комментарий

Капча загружается...