Skip to content

Commit 4698ffc

Browse files
committed
PERF: write basic datetimes faster #10271
1 parent 7516ec7 commit 4698ffc

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

doc/source/whatsnew/v0.16.2.txt

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Performance Improvements
4747
~~~~~~~~~~~~~~~~~~~~~~~~
4848

4949
- Improved ``Series.resample`` performance with dtype=datetime64[ns] (:issue:`7754`)
50+
- Modest improvement in datetime writing speed in to_csv (:issue:`10271`)
5051

5152
.. _whatsnew_0162.bug_fixes:
5253

pandas/tslib.pyx

+36-11
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@ from numpy cimport (int8_t, int32_t, int64_t, import_array, ndarray,
55
NPY_INT64, NPY_DATETIME, NPY_TIMEDELTA)
66
import numpy as np
77

8+
from cpython.ref cimport PyObject
89
from cpython cimport (
910
PyTypeObject,
1011
PyFloat_Check,
1112
PyLong_Check,
1213
PyObject_RichCompareBool,
1314
PyObject_RichCompare,
1415
PyString_Check,
15-
Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE
16+
Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE,
1617
)
1718

1819
# Cython < 0.17 doesn't have this in cpython
1920
cdef extern from "Python.h":
2021
cdef PyTypeObject *Py_TYPE(object)
2122
int PySlice_Check(object)
23+
object PyUnicode_FromFormat(const char*, ...)
2224

2325
cdef extern from "datetime_helper.h":
2426
double total_seconds(object)
@@ -1450,20 +1452,43 @@ def format_array_from_datetime(ndarray[int64_t] values, object tz=None, object f
14501452
elif basic_format:
14511453

14521454
pandas_datetime_to_datetimestruct(val, PANDAS_FR_ns, &dts)
1453-
res = '%d-%.2d-%.2d %.2d:%.2d:%.2d' % (dts.year,
1454-
dts.month,
1455-
dts.day,
1456-
dts.hour,
1457-
dts.min,
1458-
dts.sec)
1459-
14601455
if show_ns:
14611456
ns = dts.ps / 1000
1462-
res += '.%.9d' % (ns + 1000 * dts.us)
1457+
res = PyUnicode_FromFormat('%d-%02d-%02d %02d:%02d:%02d.%09d',
1458+
dts.year,
1459+
dts.month,
1460+
dts.day,
1461+
dts.hour,
1462+
dts.min,
1463+
dts.sec,
1464+
ns + 1000 * dts.us)
14631465
elif show_us:
1464-
res += '.%.6d' % dts.us
1466+
res = PyUnicode_FromFormat('%d-%02d-%02d %02d:%02d:%02d.%06d',
1467+
dts.year,
1468+
dts.month,
1469+
dts.day,
1470+
dts.hour,
1471+
dts.min,
1472+
dts.sec,
1473+
dts.us)
1474+
14651475
elif show_ms:
1466-
res += '.%.3d' % (dts.us/1000)
1476+
res = PyUnicode_FromFormat('%d-%02d-%02d %02d:%02d:%02d.%03d',
1477+
dts.year,
1478+
dts.month,
1479+
dts.day,
1480+
dts.hour,
1481+
dts.min,
1482+
dts.sec,
1483+
dts.us/1000)
1484+
else:
1485+
res = PyUnicode_FromFormat('%d-%02d-%02d %02d:%02d:%02d',
1486+
dts.year,
1487+
dts.month,
1488+
dts.day,
1489+
dts.hour,
1490+
dts.min,
1491+
dts.sec)
14671492

14681493
result[i] = res
14691494

0 commit comments

Comments
 (0)