56

How to convert a column consisting of datetime64 objects to a strings that would read 01-11-2013 for today's date of November 1.

I have tried

df['DateStr'] = df['DateObj'].strftime('%d%m%Y')

but I get this error

AttributeError: 'Series' object has no attribute 'strftime'

user2333196
  • 5,406
  • 7
  • 31
  • 35

3 Answers3

89

As of version 17.0, you can format with the dt accessor:

df['DateStr'] = df['DateObj'].dt.strftime('%d%m%Y')
Kamil Sindi
  • 21,782
  • 19
  • 96
  • 120
  • 1
    Found this really useful in using `assign`, such as: `(df .query('my query criteria here) .assign(month = lambda x: x['date'].dt.strftime('%Y-%m') )` – measureallthethings Mar 25 '16 at 17:52
  • This method will be a little faster than `df['A'].apply(lambda x: x.strftime('%d%m%Y')) `. For the 230k col, the cost time is 1.3 seconds, and that of the latter one is about 1.9 seconds. – Pengju Zhao Oct 16 '17 at 11:37
  • 1
    For larger datasets the `dt` accessor should be significantly faster as apply is more or less a for loop whereas `dt` uses C-based optimizations iirc. – Kamil Sindi Oct 16 '17 at 11:41
  • I got a warning for this: `A value is trying to be set on a copy of a slice from a DataFrame.` – Chen-CN Dec 05 '19 at 18:41
  • 1
    Sometimes a datetime conversion is needed, like so: `df['DateObj'].astype('datetime64[ns]').dt.strftime('%Y')` – PJ_ Jul 22 '22 at 18:39
51
In [6]: df = DataFrame(dict(A = date_range('20130101',periods=10)))

In [7]: df
Out[7]: 
                    A
0 2013-01-01 00:00:00
1 2013-01-02 00:00:00
2 2013-01-03 00:00:00
3 2013-01-04 00:00:00
4 2013-01-05 00:00:00
5 2013-01-06 00:00:00
6 2013-01-07 00:00:00
7 2013-01-08 00:00:00
8 2013-01-09 00:00:00
9 2013-01-10 00:00:00

In [8]: df['A'].apply(lambda x: x.strftime('%d%m%Y'))
Out[8]: 
0    01012013
1    02012013
2    03012013
3    04012013
4    05012013
5    06012013
6    07012013
7    08012013
8    09012013
9    10012013
Name: A, dtype: object
Jeff
  • 125,376
  • 21
  • 220
  • 187
0

It works directly if you first set as index. Then essentially you pass a 'DatetimeIndex' object and not a 'Series'

df = df.set_index('DateObj').copy()    
df['DateStr'] = df.index.strftime('%d%m%Y')