Установите формат для pd.to_datetime - PullRequest
0 голосов
/ 20 мая 2018

Привет уже упомянул к этому сообщению , но я не смог пройти через мою проблему.У меня есть столбец в моем CSV, который является строкой, и примеры значений приведены ниже (обратите внимание, что позиционирование month и year иногда меняется на противоположное).Какой формат мне нужно установить в моем to_datetime?Я испробовал все нижеприведенные подходы

df = pd.read_csv("filename.csv") #Imagine there is a Month column

#[1] df["Month"] = pd.to_datetime(df["Month"])
#[2] df["Month"] = pd.to_datetime(df["Month"], format="%m/%d/%Y")

[Month]
Mar-97
Apr-97
May-97
Jun-97
Nov-00
Dec-00
1-Jan
1-Feb
1-Mar
1-Apr

Я получаю ошибку

ValueError: день выходит за пределы диапазона для месяца

для [1]и я получаю

ValueError: данные времени 'Mar-97' не соответствуют формату '% m /% d /% Y' (соответствует)

для [2].Я тоже пытался удалить %d, но безуспешно.Не могли бы вы указать мне, что здесь происходит не так.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Не самый элегантный, но вы можете попробовать починить и заказать детали года и месяца.Приведенный ниже код работает:

Восстановите ваши данные:

df = pd.DataFrame({"date_str": ['Mar-97', 'Apr-97', 'May-97', 
                                'Jun-97', 'Nov-00', 'Dec-00',
                                '1-Jan', '1-Feb', '1-Mar', '1-Apr']})

Разделите части:

df = pd.concat([df, df['date_str'].str.split("-", expand=True)], axis=1)

Организуйте месяц и год:

df.loc[df[0].str.len() == 3, 'month'] = df.loc[df[0].str.len() == 3, 0]
df.loc[df[1].str.len() == 3, 'month'] = df.loc[df[1].str.len() == 3, 1]
df.loc[df[0].str.len() != 3, 'year'] = df.loc[df[0].str.len() != 3, 0]
df.loc[df[1].str.len() != 3, 'year'] = df.loc[df[1].str.len() != 3, 1]

Правильные годы, состоящие только из одной цифры:

df.loc[df['year'].str.len() == 1, 'year'] = '0' + df.loc[df['year'].str.len() == 1, 'year']

Создание правильного столбца даты:

df['date'] = (df['month'] + '-' + df['year']).apply(lambda x: pd.to_datetime(x, format="%b-%y"))

Вывод:

print (df ['date')])

0   1997-03-01
1   1997-04-01
2   1997-05-01
3   1997-06-01
4   2000-11-01
5   2000-12-01
6   2001-01-01
7   2001-02-01
8   2001-03-01
9   2001-04-01
Name: date, dtype: datetime64[ns]
0 голосов
/ 20 мая 2018

Одним из способов является использование try / except с pd.Series.apply:

s = pd.Series(['Mar-97', 'May-97', 'Nov-00', '1-Jan', '1-Mar'])

def converter(x):
    try:
        return pd.datetime.strptime(x, '%b-%y')
    except ValueError:
        year, month = x.split('-')  # split by delimiter
        x = year.zfill(2) + '-' + month  # %y requires 0-padding
        return pd.datetime.strptime(x, '%y-%b')

res = s.apply(converter)

print(res)

0   1997-03-01
1   1997-05-01
2   2000-11-01
3   2001-01-01
4   2001-03-01
dtype: datetime64[ns]

Поскольку мы определили converter как функцию, мы можем использовать это непосредственно с pd.read_csv:

df = pd.read_csv('file.csv', parse_dates=['dt_col_name'], date_parser=converter)

Директивы Python strftime - полезная ссылка для построения строк формата datetime.

...