Вопрос или проблема
Я работал с набором данных SpaceShip Titanic от Kaggle и проводил анализ данных. Обозначим tt
как pd.DataFrame
, содержащий данные. Я суммировал все денежные переменные, а затем попытался отфильтровать, чтобы получить только те строки, где TotalExp==0 и CryoSleep.isna()
, но в результатах я получаю как людей с CryoSleep не nan, так и людей с TotalExp не 0
monetary = ['RoomService', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']
tt.loc[:,'TotalExp'] = tt.loc[:,monetary].sum(axis=1)
tt.loc[np.where((tt.TotalExp == 0.0) & (tt.CryoSleep.isna()))][['CryoSleep','TotalExp']]
Пример текущего вывода:
индекс | CryoSleep | TotalExp |
---|---|---|
1405 | NaN | 977.0 |
1417 | False | 0.0 |
1454 | NaN | 3862.0 |
1531 | NaN | 0.0 |
1565 | NaN | 906.0 |
Я пробовал оба фильтра отдельно, и поведение в каждом случае одинаковое (принося случаи, которые не должны быть).
Ожидаемое поведение заключается в том, что отображаются только строки, где CryoSleep является NaN и TotalExp = 0, оба одновременно.
Что я упускаю?
Чтобы исправить код для выбора строк, где CryoSleep
является NaN
и TotalExp
равен 0
, вы можете изменить последнюю строку кода следующим образом: Я работаю с образцом DataFrame
import pandas as pd
import numpy as np
# создаем образец dataframe
tt = pd.DataFrame({
'RoomService': [10, 0, 20, 0, 30],
'FoodCourt': [20, 0, 30, 0, 40],
'ShoppingMall': [30, 0, 40, 0, 50],
'Spa': [40, 0, 50, 0, 60],
'VRDeck': [50, 0, 60, 0, 70],
'CryoSleep': [np.NaN, 1, 0, 1, np.NaN]
})
# суммируем денежные столбцы и присваиваем в столбец TotalExp
monetary = ['RoomService', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']
tt.loc[:, 'TotalExp'] = tt.loc[:, monetary].sum(axis=1)
# выбираем строки, где CryoSleep является NaN и TotalExp равен 0
selected_data = tt.loc[(tt['CryoSleep'].isna()) & (tt['TotalExp'] == 0), ['CryoSleep', 'TotalExp']]
# печатаем выбранные данные
print(selected_data)
Вам не нужно использовать np.where
, чтобы получить результат, но если вы все же хотите использовать эту функцию, попробуйте следующий код;
selected_data = tt.loc[np.where((tt['CryoSleep'].isna()) & (tt['TotalExp'] == 0)), ['CryoSleep', 'TotalExp']]
```
Ответ или решение
Применение фильтрации в Pandas с использованием np.where в наборе данных SpaceShip Titanic
При работе с библиотекой Pandas для анализа данных в Kaggle’s SpaceShip Titanic dataset, у вас возникла проблема с фильтрацией, когда результат не соответствует ожидаемому. Конкретно, вы хотите отфильтровать строки, где TotalExp == 0
и CryoSleep.isna()
одновременно, но в выводе оказывается много лишних данных.
Причина проблемы
На первый взгляд, использование np.where
в вашем коде выглядит корректным, однако основная проблема кроется в том, как выполняется операция логического "И" (&
). В вашем коде:
tt.loc[np.where((tt.TotalExp == 0.0) & (tt.CryoSleep.isna()))][['CryoSleep','TotalExp']]
По сути, использование np.where
в этом контексте избыточно и может привести к путанице, так как функция np.where
возвращает индексы, а не логические массивы, что может быть не совсем ясно в вашем случае.
Решение проблемы
Для фильтрации данных в DataFrame, использование прямого логического условия будет более эффективным и понятным. Вы можете переписать ваш код следующим образом:
import pandas as pd
import numpy as np
# Создаем пример DataFrame
tt = pd.DataFrame({
'RoomService': [10, 0, 20, 0, 30],
'FoodCourt': [20, 0, 30, 0, 40],
'ShoppingMall': [30, 0, 40, 0, 50],
'Spa': [40, 0, 50, 0, 60],
'VRDeck': [50, 0, 60, 0, 70],
'CryoSleep': [np.NaN, 1, 0, 1, np.NaN]
})
# Суммируем денежные столбцы и присваиваем результат в столбец TotalExp
monetary = ['RoomService', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']
tt['TotalExp'] = tt[monetary].sum(axis=1)
# Отбираем строки, где CryoSleep равен NaN и TotalExp равен 0
selected_data = tt[(tt['CryoSleep'].isna()) & (tt['TotalExp'] == 0)][['CryoSleep', 'TotalExp']]
# Печатаем отобранные данные
print(selected_data)
Альтернативный подход с использованием np.where
Если вы все же хотите использовать np.where
, следует это делать так:
selected_data = tt.loc[np.where((tt['CryoSleep'].isna()) & (tt['TotalExp'] == 0)), ['CryoSleep', 'TotalExp']]
Однако, как упоминалось ранее, данный подход не является лучшим в данном случае.
Заключение
Использование логической фильтрации напрямую через логические условия в Pandas является более понятным и предпочтительным методом для решения вашей задачи. Таким образом, вы сможете избежать путаницы с использованием np.where
и сразу извлекать нужные вам данные. Главное – обращайте внимание на то, что возвращают ваши методы, чтобы не попасть в ловушку неправильной интерпретации возвращаемых значений. Надеюсь, это поможет вам в ваших дальнейших анализах!