Вопрос или проблема
У меня ошибка, когда я пытаюсь запустить этот код
import pandas as pd
import numpy as np
import seaborn as sns
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
sns.set_theme()
sns.set_style('white')
df_train = pd.read_csv('https://github.com/lokalhangatt/stackoverlow/raw/refs/heads/main/train.csv')
df_train = df_train.dropna(axis=1)
null_info = df_train.isnull().sum().sort_values(ascending=False).reset_index().head(20)
null_info.columns = ["Переменная", "Пропущенное значение"]
list_soal = ['SalePrice', 'GrLivArea', 'GarageArea']
# fig,ax = plt.subplots(1, 3, sharey=True, figsize=(14,4))
def function1(ax):
ax[1].set_title('Гистограмма для не трансформированных данных', fontsize=16)
for i in range(len(list_soal)):
sns.histplot(df_train[list_soal[i]], kde=False, stat="density", bins = 30, ax=ax[i])
sns.kdeplot(df_train[list_soal[i]], ax=ax[i])
for j in range(len(list_soal)):
line1 = plt.axvline(df_train[list_soal].mean(), color="k", linestyle="--", label = "среднее")
line2 = plt.axvline(np.median(df_train[list_soal]), color="r", linestyle="--", label = "медиана")
first_legend = plt.legend(handles=[line1,line2], loc=1)
# fig,ax = plt.subplots(1, 3, sharey=True, figsize=(14,4))
def function2(ax):
ax[1].set_title('Гистограмма для трансформированных данных', fontsize=16)
for i in range(len(list_soal)):
sns.histplot(np.log10(df_train[list_soal[i]]), kde=False, stat="density", bins = 30, ax=ax[i])
sns.kdeplot(np.log10(df_train[list_soal[i]]), ax=ax[i])
fig,ax = plt.subplots(2, 3, figsize=(14,9), sharey='row')
fig.subplots_adjust(hspace=0.4)
function1(ax[0])
function2(ax[1])
plt.show()
Я хочу отобразить центральные тенденции на каждом субплоте, который я запускаю. Вот мои субплоты:
Это должно показать центральную тенденцию каждого бокса на субплотах. Но когда я пытаюсь запустить код выше, я получаю ошибку, которая говорит:
ValueError: Истинное значение серии неоднозначно. Используйте a.empty, a.bool(), a.item(), a.any() или a.all().
Как я могу показать эти центральные тенденции на каждом субплоте?
Ответ или решение
Для успешного построения субплотов с центральными тенденциями (среднее, медиана, мода) в библиотеке Seaborn и устранения ошибки, с которой вы столкнулись, необходимо внести некоторые изменения в ваш исходный код. Ошибка ValueError: The truth value of a Series is ambiguous
возникает, когда вы пытаетесь передать целую серию данных в функцию, которая ожидает одиночное значение.
Расмотрим обновленный код, в который включены необходимые исправления для правильного отображения центральных тенденций для каждого графика в субплотах.
Исправленный код для построения субплотов с центральными тенденциями
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# Настройка стиля и темы
sns.set_theme()
sns.set_style('white')
# Загрузка данных
df_train = pd.read_csv('https://github.com/lokalhangatt/stackoverlow/raw/refs/heads/main/train.csv')
df_train = df_train.dropna(axis=1)
# Определение переменных для анализа
list_soal = ['SalePrice', 'GrLivArea', 'GarageArea']
# Функция для построения гистограмм для не трансформированных данных
def function1(ax):
ax[1].set_title('Histogram for Non-Transformed Data', fontsize=16)
for i in range(len(list_soal)):
sns.histplot(df_train[list_soal[i]], kde=False, stat="density", bins=30, ax=ax[i])
sns.kdeplot(df_train[list_soal[i]], ax=ax[i])
# Добавление линий для среднего и медианы
ax[i].axvline(df_train[list_soal[i]].mean(), color="k", linestyle="--", label="mean")
ax[i].axvline(df_train[list_soal[i]].median(), color="r", linestyle="--", label="median")
ax[i].legend()
# Функция для построения гистограмм для трансформированных данных
def function2(ax):
ax[1].set_title('Histogram for Transformed Data', fontsize=16)
for i in range(len(list_soal)):
transformed_data = np.log10(df_train[list_soal[i]])
sns.histplot(transformed_data, kde=False, stat="density", bins=30, ax=ax[i])
sns.kdeplot(transformed_data, ax=ax[i])
# Добавление линий для среднего и медианы
ax[i].axvline(transformed_data.mean(), color="k", linestyle="--", label="mean")
ax[i].axvline(transformed_data.median(), color="r", linestyle="--", label="median")
ax[i].legend()
# Настройка субплотов
fig, ax = plt.subplots(2, 3, figsize=(14, 9), sharey='row')
fig.subplots_adjust(hspace=0.4)
# Построение графиков
function1(ax[0])
function2(ax[1])
# Отображение графиков
plt.show()
Пояснения к изменениям
-
Ошибка передавалась в функции: В оригинальном коде вы использовали
df_train[list_soal].mean()
иdf_train[list_soal].median()
, что возвращало Series, а не отдельное значение. Вместо этого мы изменили код, чтобы получать среднее и медиану для каждого элемента вlist_soal
отдельно. -
Легенда на каждом субплоте: Легенды теперь добавляются в цикле для каждого субплота, что улучшает читаемость графиков и позволяет легко различить, какая линия представляет среднее, а какая медиану.
-
Структурировка кода: Удалены ненужные переменные и неиспользуемые импорты, что делает код более чистым и понятным.
Заключение
Теперь ваш код корректно отображает центральные тенденции для каждого субплота как для не трансформированных, так и для трансформированных данных, и дополнительные изменения упрощают понимание и читабельность графиков. Вы можете адаптировать данный код к своей задаче для изучения различных переменных с помощью Seaborn.