@LetMeDieYung

Как выбрать правильно выбрать период в pandas?

У меня есть программа на Python, которая рассчитывает метеорологические данные. Однако на данный момент она некорректно выбирает дату, и она выбирает "зимние месяцы" для каждого года и рассчитывает по ним. Но мне нужно, чтобы начальная дата для каждого года рассчитывалась относительно столбца T, где указаны показатели температуры. Начало зимы будет определяться, когда будет 5 отрицательных значений температуры подряд, а конец зимы - когда будет 5 положительных значений. Приложены код и скриншоты программы ниже.
Запуск программы:
6489e0037df2d466431647.png

6489e025a94cf249027577.png

Фрагмент кода с выбором периода и дат:
# Загрузка данных из файла Excel
xls = pd.ExcelFile('DB_Arctic.xls')

# Получение списка имен листов
sheet_names = xls.sheet_names

while True:
    selected_sheet = int(input("Введите номер станции: "))

    selected_sheet = selected_sheet-1

    selected_sheet = sheet_names[selected_sheet]

    df = pd.read_excel(xls, sheet_name=selected_sheet)

    # Удаление времени из столбца 't' и оставление только даты
    df['t'] = pd.to_datetime(df['t'], format='%d.%m.%Y %H:%M', errors='coerce').dt.date

    # Ввод года от пользователя
    selected_start_year = int(input("Введите начало периода: "))
    selected_end_year = int(input("Введите конец периода: "))

    # Функция для проверки зимних месяцев
    def is_winter_month(date):
        month = date.month
        return month in [10, 11, 12, 1, 2, 3]

    # Определение начального и конечного года в зависимости от введенных пользователем значений.
    start_year = selected_start_year - 1
    end_year = selected_end_year

    # Создание начальной и конечной даты для каждого года
    start_date = datetime.date(start_year, 10, 1)
    end_date = datetime.date(end_year, 3, 1)

    # Цикл по зимним периодам в заданном диапазоне дат
    while start_date < end_date:
        # Выбор текущего года
        current_year = start_date.year

        # Создание даты начала и конца зимнего периода для текущего года
        winter_start_date = datetime.date(current_year, 10, 1)
        winter_end_date = datetime.date(current_year + 1, 3, 1)


        # Функция для проверки зимних месяцев
        def is_winter_month(date):
            month = date.month
            return month in [10, 11, 12, 1, 2, 3]

        # Выбор данных только для зимних месяцев и определенного периода
        df_selected_year = df[df['t'].apply(lambda x: is_winter_month(x)) &
                              ((df['t'] >= start_date) & (df['t'] < end_date))]

        # Расчет средних значений по датам
        average_values = round(df_selected_year.groupby('t')['T'].mean().reset_index(),1)

...Остальные рассчеты.....
  # Переход к следующему году
        start_date = datetime.date(current_year + 1, 10, 1)

...Вывод графиков и т.п...


структура файлы xls:
6489e1abaafcd127154458.png

Если нужны доп.данные, предоставлю
  • Вопрос задан
  • 173 просмотра
Пригласить эксперта
Ответы на вопрос 1
Maksim_64
@Maksim_64
Data Analyst
Ну во первых ты не представил игрушечного датафрейма (входные данные), и каков желаемый результат (выходные данные).

Вместо этого ты дал фрагмент кода не связанного с проблемой по всей видимости код был написан chatGPT, по скольку он очень низкого качества и попросту странный очень на вряд ли даже начинающий программист напишет такой pandas код.

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

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'temperature':[
        1.5,1,4,-2,1,-1,-1,4,3,2,1,-2,-3,-4,-5,-6,-1,2,-2,-2,-3,4,-5,-3,3,1,2,5,3,2
    ]
}, index = pd.date_range('2023-01-01', periods=30))


negative_groups = (
    df
    .query('temperature < 0')
    .groupby((df.temperature > 0).cumsum())
)
positive_groups = (
        df
        .query('temperature >= 0')
        .groupby((df.temperature < 0).cumsum())
)
start_date = [value for value in negative_groups.groups.values() if len(value) >=5][0][4]
end_date = [value for value in positive_groups.groups.values() if len(value) >=5][0][4]

df.loc[start_date:end_date]


Я создал фрейм, и вытащил из него индексы даты, 5-го значения для последовательно отрицательных элементов. Как начало зимы и индекс даты 5-го значения для последовательности положительных элементов. И осуществил выборку между этими датами.

Заметь, если у нас например 6 повторяющихся отрицательных элементов то он он возьмет дату 5 так как по условию если 5 то начало зимы и если 5 то конец.

Ну распечатай фрейм и распечатай выборку подсета из фрейма и убедишься, что работает правильно. Бери мой пример и прикручивай его к своим данным. Не забудь дату поставить в индекс и не забудь что бы у даты был тип данных date а не object.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы