2015-09-28 2 views
3

У меня есть dataframe, который содержит столбец, который держит:Панды: Изменение даты в dataframe на тот же формат даты

Date: 
31MAR2005 
30-06-05 
311205 

Я хотел бы преобразовать эти даты в формате: 30-06-05 (dd- MM-JJ). Каков самый простой способ сделать это? Поля еще не в формате даты, только строки.

+1

ли эти три типа шаблонов для строк? Или есть еще больше шаблонов (возможно, некоторые из них вы даже не знаете?)? Во-вторых, если есть общие шаблоны, знаете ли вы строки, в которых будут отображаться эти шаблоны? – measureallthethings

+0

@measureallthethings, эти три являются единственными образцами, которые существуют в этой колонке. Я не знаю конкретных строк, в которых они происходят. – F1990

+0

Если это единственные 3 паттерна, я бы предложил создать функцию с использованием некоторого распознавания строки и strptime, а затем применить ее к вашему фреймворку данных. – Alex

ответ

2

Вы можете использовать Pandas' vectorize string methods извлечь день, месяц и год от каждой строки даты:

import pandas as pd 

df = pd.DataFrame(['31MAR2005', '30-06-05', '311205'], columns=['Date']) 
tmp = df['Date'].str.extract(r'(\d{2})-?(\D{3}|\d{2})-?.*(\d{2})') 
tmp.columns = ['day', 'month', 'year'] 

дает

In [228]: tmp 
Out[228]: 
    day month year 
0 31 MAR 05 
1 30 06 05 
2 31 12 05 

Теперь вы можете изменить 3-буквенный месяц сокращение числовых строк с помощью вызова Series.map:

import calendar 
monthmap = {calendar.month_abbr[i].upper(): '{:02d}'.format(i) for i in range(1, 13)} 
monthmap.update({'{:02d}'.format(i):'{:02d}'.format(i) for i in range(1, 13)}) 
tmp['month'] = tmp['month'].map(monthmap) 

дает

In [230]: tmp 
Out[230]: 
    day month year 
0 31 03 05 
1 30 06 05 
2 31 12 05 

И, наконец, вы можете переназначить df['Date'] в нужный формат даты-строки:

df['Date'] = tmp['day']+'-'+tmp['month']+'-'+tmp['year'] 

дает

In [232]: df 
Out[232]: 
     Date 
0 31-03-05 
1 30-06-05 
2 31-12-05 

Особенно, если DataFrame длинный, используя векторизованную строку методы должны быть быстрее, чем использование df.apply для вызова функции Python один раз для каждого значения строки.

Также обратите внимание, что это выполняет задачу без разбора строк как Временные метки. Это может быть хорошо или плохо. С одной стороны, это может повысить производительность. С другой стороны, с , это может привести к пропуску недопустимых строк даты (например, '30FEB2005').

После повторного форматирования строки, вы могли бы назвать

df['Date'] = pd.to_datetime(df['Date']) 

преобразовать строки даты в соответствующую Timestamps. Тогда недопустимые строки даты станут значениями NaT (Not-a-Timestamp).

2

Вот мой пример:

def string_to_date(my_string): 
    if '-' in my_string: 
     return datetime.datetime.strptime(my_string, '%d-%m-%y') 
    elif my_string.isdigit(): 
     return datetime.datetime.strptime(my_string, '%d%m%y') 
    elif my_string.isalnum(): 
     return datetime.datetime.strptime(my_string, '%d%b%Y') 

Сейчас я тестирую его на dataframe ДФ:

In[116]: df['Date:'].apply(lambda x: string_to_date(x)) 
Out[114]: 
0 2005-03-31 
1 2005-06-30 
2 2005-12-31 
Name: Date:, dtype: datetime64[ns] 
Смежные вопросы