Ошибка при работе с DataFrame в Python

При работе с DataFrame в Python с использованием Pandas и NumPy возникает интересная ошибка.

При создании нового столбца мне нужно вырезать из даты формата "1995-10-30" число месяца. Когда я пытаюсь получить второй элемент даты split('-')[1] у меня возникает ошибка. А если я передам split('-')[0] то ошибки нет, но создается столбец годом.

Кусочек кода:

df['release_month'] = pd.to_datetime(df['release_date'], errors='coerce').apply(lambda x: str(x).split('-')[1] if x != np.nan else np.nan)

Текст ошибки:

Traceback (most recent call last):
  File "C:\Users\Сергей\PycharmProjects\pythonProject\main.py", line 44, in <module>
    df['release_month'] = pd.to_datetime(df['release_date'], errors='coerce').apply(lambda x: str(x).split('-')[1] if x != np.nan else np.nan)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\series.py", line 4924, in apply
    ).apply()
      ^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\apply.py", line 1427, in apply
    return self.apply_standard()
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\apply.py", line 1507, in apply_standard
    mapped = obj._map_values(
             ^^^^^^^^^^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\base.py", line 919, in _map_values
    return arr.map(mapper, na_action=na_action)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\arrays\_mixins.py", line 81, in method
    return meth(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\arrays\datetimelike.py", line 740, in map
    result = map_array(self, mapper, na_action=na_action)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Сергей\PycharmProjects\pythonProject\venv\Lib\site-packages\pandas\core\algorithms.py", line 1743, in map_array
    return lib.map_infer(values, mapper, convert=convert)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "lib.pyx", line 2972, in pandas._libs.lib.map_infer
  File "C:\Users\Сергей\PycharmProjects\pythonProject\main.py", line 44, in <lambda>
    df['release_month'] = pd.to_datetime(df['release_date'], errors='coerce').apply(lambda x: str(x).split('-')[1] if x != np.nan else np.nan)
                                                                                              ~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

Process finished with exit code 1

Ответы (2 шт):

Автор решения: Oopss

А что месяц нельзя просто вынести?

import pandas as pd


data = {'date': ['1995-10-30', '1996-11-25', '1997-12-20']}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month

print(df)

        date  month
0 1995-10-30     10
1 1996-11-25     11
2 1997-12-20     12
→ Ссылка
Автор решения: CrazyElf

Кроме того, что метод не оптимален и лучше работать прямо с датами, нужно бы знать, что сравнения вида if x != np.nan работают не так, как вы думаете. NA никогда не будет равно NA, ваша проверка в if всегда будет истинна. Потому что NA - это специальный объект, который не равен не только числам, но и сам себе. Это неопределённость, она не может быть ничему равна. И проверять её нужно по-другому. Вот пример не правильного сравнения и правильной проверки:

print(np.nan == np.nan) # False
print(np.isnan(np.nan)) # True
→ Ссылка