Setup
df = pd.DataFrame(dict(
A='XX YY ZZ AA'.split(),
Date=pd.date_range('2017-03-31', periods=4)
))
Option 1
apply
with a lambda
based on format
and dictionary unpacking.
This is a slow, but cool way to do it.
df.assign(C=df.apply(lambda x: '{Date:%Y-%m-%d}_{A}'.format(**x), 1))
A Date C
0 XX 2017-03-31 2017-03-31_XX
1 YY 2017-04-01 2017-04-01_YY
2 ZZ 2017-04-02 2017-04-02_ZZ
3 AA 2017-04-03 2017-04-03_AA
Option 2
numpy.core.defchararray.add
Very fast way to do it using 'datetime64[D]'
to round to the day.
chr_add = np.core.defchararray.add
d = df.Date.values.astype('datetime64[D]').astype(str)
a = df.A.values.astype(str)
df.assign(C=chr_add(chr_add(d, '_'), a))
A Date C
0 XX 2017-03-31 2017-03-31_XX
1 YY 2017-04-01 2017-04-01_YY
2 ZZ 2017-04-02 2017-04-02_ZZ
3 AA 2017-04-03 2017-04-03_AA
Option 3
Rip-off of @AndyHayden's answer with a small twist. I'll add my underscore '_'
in the strftime
... Mainly, this is what I'll use in timeit
.
df.assign(C=df.Date.dt.strftime('%Y-%m-%d_') + df.A)
A Date C
0 XX 2017-03-31 2017-03-31_XX
1 YY 2017-04-01 2017-04-01_YY
2 ZZ 2017-04-02 2017-04-02_ZZ
3 AA 2017-04-03 2017-04-03_AA
Timing
%%timeit
chr_add = np.core.defchararray.add
d = df.Date.values.astype('datetime64[D]').astype(str)
a = df.A.values.astype(str)
chr_add(chr_add(d, '_'), a)
%timeit df.assign(C=df.apply(lambda x: '{Date:%Y-%m-%d}_{A}'.format(**x), 1))
%timeit df.assign(C=df.Date.dt.strftime('%Y-%m-%d_') + df.A)
small data
10000 loops, best of 3: 53.2 µs per loop
1000 loops, best of 3: 1.14 ms per loop
1000 loops, best of 3: 831 µs per loop
large data
df = pd.concat([df] * 10000, ignore_index=True)
10 loops, best of 3: 80.3 ms per loop
1 loop, best of 3: 4.58 s per loop
1 loop, best of 3: 233 ms per loop