Вопрос или проблема
У меня есть серия Pandas с множеством нулевых значений и индексом DateTime. Я хочу построить график, на котором будут видны только некоторые нулевые значения и правильно обработано временное пространство.
Например, серия выглядит следующим образом. Простой график показывает слишком много нулей. Я хочу показать только несколько нулей до и после ненулевых значений. И в то же время правильно скрыть даты между ними.
ser_tmp = pd.Series(0, index=pd.date_range('2020-01-01', '2020-01-30'))
ser_tmp.loc[[pd.Timestamp('2020-01-03'), pd.Timestamp('2020-01-04'), pd.Timestamp('2020-01-23'), pd.Timestamp('2020-01-24')]] = 1
ser_tmp.plot()
График после замены всех нулей не то, что я хочу.
ser_tmp.replace(0, np.nan).plot()
То, что я хочу, это что-то вроде ser_tmp2
. Но построение ser_tmp2
не скрывает промежуток дат между 2020-01-06
и 2020-01-21
. Более того, я хотел бы автоматически определять даты, а не задавать нули, как в ser_tmp2
, вручную.
ser_tmp2 = ser_tmp.replace(0, np.nan).copy()
ser_tmp2.loc[[pd.Timestamp('2020-01-01'), pd.Timestamp('2020-01-02'), pd.Timestamp('2020-01-05'), pd.Timestamp('2020-01-06'), pd.Timestamp('2020-01-21'), pd.Timestamp('2020-01-22'), pd.Timestamp('2020-01-25'), pd.Timestamp('2020-01-26')]] = 0
ser_tmp2 = ser_tmp2.dropna()
ser_tmp2
ser_tmp2.plot()
Если я правильно понял вас, вы хотите удалить несколько последовательных нулей.
Мое решение:
ser_tmp = pd.Series(0, index=pd.date_range('2020-01-01', '2020-01-30'))
ser_tmp.loc[[pd.Timestamp('2020-01-03'), pd.Timestamp('2020-01-04'), pd.Timestamp('2020-01-23'), pd.Timestamp('2020-01-24')]] = 1
ser_tmp.index = ser_tmp.index.strftime('%Y-%m-%d') # Устанавливаем индекс как строку, чтобы он не добавлял автоматически недостающие даты
ser_tmp.drop(ser_tmp[(ser_tmp == 0) & (ser_tmp.shift(1) == 0) & (ser_tmp.shift(-1) == 0)].index, inplace=True) # Удаляем все нулевые значения, которые имеют ноль до и ноль после как значения
ser_tmp.plot(rot=45)
Результат:
Код
# создаем условие
cond = ser_tmp.ne(0).rolling(5, min_periods=1, center=True).sum() > 0
# фильтруем и сбрасываем индекс и так далее.
tmp = ser_tmp[cond].rename_axis('date').reset_index(name="val")
# Строим график отфильтрованных данных с повёрнутыми метками оси x
ax = tmp['val'].plot(rot=45)
# устанавливаем все индексы как метки по оси x и используем их в качестве меток
ax.set_xticks(tmp.index)
ax.set_xticklabels(tmp['date'].dt.strftime('%y/%m/%d'))
Ответ или решение
Чтобы корректно визуализировать временной ряд с нулевыми значениями в Pandas, используя DateTimeIndex, и избежать чрезмерного отображения нулей на графике, можно воспользоваться следующим пошаговым подходом. Мы будем исключать из выборки многократные последовательные нули, оставляя лишь нужные нулевые значения, чтобы график отображал только ключевые данные.
Шаг 1: Инициализация и создание Series
Сначала создадим Pandas Series
с нулевыми значениями и несколькими ненулевыми значениями по заданной дате:
import pandas as pd
# Создаем Series со значением 0 на указанном диапазоне дат
ser_tmp = pd.Series(0, index=pd.date_range('2020-01-01', '2020-01-30'))
ser_tmp.loc[[pd.Timestamp('2020-01-03'), pd.Timestamp('2020-01-04'), pd.Timestamp('2020-01-23'), pd.Timestamp('2020-01-24')]] = 1
Шаг 2: Удаление ненужных нулей
Для того чтобы убрать ненужные последовательные нулевые значения, мы можем воспользоваться функцией shift()
и создадим условие, при котором оставим только первые и последние нули. В результате отфильтруем значения, которые находятся между ненулевыми значениями.
# Условие для удаления последовательных нулей
mask = ser_tmp.ne(0).rolling(5, min_periods=1, center=True).sum() > 0
# Фильтруем Series
filtered_series = ser_tmp[mask]
Шаг 3: Визуализация данных
Теперь, когда мы подготовили наши данные и исключили ненужные нули, мы можем построить график:
import matplotlib.pyplot as plt
# Визуализируем отфильтрованный Series
filtered_series.plot(rot=45)
# Настроим подписи осей и заголовок
plt.title('Построение временного ряда с нулями внутри')
plt.xlabel('Дата')
plt.ylabel('Значение')
plt.show()
Шаг 4: Дополнительная настройка графика
Для более тонкой настройки графика и контроля за появлением меток можно воспользоваться дополнительными манипуляциями с осями и метками:
ax = filtered_series.plot(rot=45)
ax.set_xticks(filtered_series.index)
ax.set_xticklabels(filtered_series.index.date)
Заключение
Используя вышеописанные шаги, вы сможете построить график временного ряда с DateTimeIndex, который будет правильно визуализировать ключевые значения, не загромождая его ненужными нулями. Данный метод также позволяет легко манипулировать данными, чтобы соответствовать вашим конкретным требованиям визуализации. Убедитесь, что вы корректно задаете условия фильтрации, чтобы график отображал именно ту информацию, которая вам требуется.