Поиск последовательных дат с помощью Python

У меня есть набор данных НБА, который выглядит так:

Игрок Дата_игры Леброн Джеймс 2023-10-11 Леброн Джеймс 2023-10-12 Леброн Джеймс 2023-10-18 Коби Брайант 2023-11-02 Коби Брайант 03.11.2023 Коби Брайант 09.11.2023

И я хочу отфильтровать его, чтобы он включал только последовательные игры, чтобы он выглядел так:

Игрок Дата_игры Леброн Джеймс 2023-10-11 Леброн Джеймс 2023-10-12 Коби Брайант 2023-11-02 Коби Брайант 03.11.2023

Пожалуйста, считайте, что это всего лишь фрагмент всего моего набора данных, поэтому мне, надеюсь, нужно будет найти способ отфильтровать весь набор данных, а не только этот небольшой фрагмент.

Если вы хотите создать фрейм данных:

data = [
{'Player': 'Lebron James', 'Game_date': '2023-10-11'},
{'Player': 'Lebron James', 'Game_date': '2023-10-12'},
{'Player': 'Lebron James', 'Game_date': '2023-10-18'},
{'Player': 'Kobe Bryant', 'Game_date': '2023-11-02'},
{'Player': 'Kobe Bryant', 'Game_date': '2023-11-03'},
{'Player': 'Kobe Bryant', 'Game_date': '2023-11-09'},
]
df = pd.DataFrame(data)
print(df)

Я попробовал сделать это:

# Convert 'game_date' column to datetime format
df['game_date'] = pd.to_datetime(df['game_date']).dt.date

# Sort DataFrame by player_id and game_date
df.sort_values(by=['player_name', 'game_date'], inplace=True)

# Calculate the difference between consecutive game dates and store the result in 'b2b' column
df['b2b'] = df.groupby('player_name')['game_date'].apply(lambda x:x.diff().fillna(pd.Timedelta(days=0))).dt.days

Хотите найти две или более игры подряд? Или ровно два?

John Gordon 15.03.2024 01:45

Поскольку это НБА, в ней будет только две игры подряд. Так что ровно два!

Sam Ash 15.03.2024 01:50

Убедитесь, что записи игр отсортированы сначала по игроку, а затем по дате. Затем просмотрите игровые записи. Если в текущей записи игры указан тот же игрок, что и в следующей записи игры, а даты игр отличаются на один день, то вы нашли последовательные игры. В чем сложность?

John Gordon 15.03.2024 02:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте groupby.transform и diff , чтобы проверить, являются ли дни последовательными, затем сдвиньте маску назад на один шаг, чтобы включить начальную строку, и, наконец, выполните логическое индексирование:

# ensure datetime (NOT date!)
df['Game_date'] = pd.to_datetime(df['Game_date'])

# identify rows to keep
keep = (df.groupby('Player')['Game_date']
          .transform(lambda g: (m:=g.diff().dt.days.eq(1)) | m.shift(-1))
       )

# select
out = df.loc[keep]

Выход:

         Player  Game_date
0  Lebron James 2023-10-11
1  Lebron James 2023-10-12
3   Kobe Bryant 2023-11-02
4   Kobe Bryant 2023-11-03

Промежуточные уровни (с двумя дополнительными свиданиями, чтобы продемонстрировать несколько последовательных свиданий для каждого игрока):

         Player  Game_date    diff      m m.shift(-1)  m|m.shift(-1)
0  Lebron James 2023-10-11     NaT  False        True           True
1  Lebron James 2023-10-12  1 days   True       False           True
2  Lebron James 2023-10-18  6 days  False         NaN          False
3   Kobe Bryant 2023-11-02     NaT  False        True           True
4   Kobe Bryant 2023-11-03  1 days   True       False           True
5   Kobe Bryant 2023-11-09  6 days  False       False          False
6   Kobe Bryant 2023-12-11 32 days  False        True           True
7   Kobe Bryant 2023-12-12  1 days   True         NaN           True

Другие вопросы по теме