Skip to content

Commit

Permalink
Circumvent Pandas bugs for years > 2262
Browse files Browse the repository at this point in the history
  • Loading branch information
berland committed Jan 20, 2023
1 parent 338df6d commit bfd3574
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
13 changes: 9 additions & 4 deletions python/ecl/summary/ecl_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ def pandas_frame(self, time_index=None, column_keys=None):
raise ValueError("No valid key")

if time_index is None:
time_index = self.numpy_dates
time_index = self.dates
data = numpy.zeros([len(time_index), len(keywords)])
EclSum._init_pandas_frame(
self, keywords, data.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
Expand Down Expand Up @@ -635,16 +635,21 @@ def _compile_headers_list(headers, dims):
@classmethod
def from_pandas(cls, case, frame, dims=None, headers=None):
start_time = frame.index[0]

# Avoid Pandas or numpy timestamps, to avoid Pandas attempting to create
# timestamp64[ns] indices (which can't go beyond year 2262)
# https://github.com/pandas-dev/pandas/issues/39727
if isinstance(start_time, pandas.Timestamp):
start_time = start_time.to_pydatetime()

var_list = []
if headers is None:
header_list = EclSum._compile_headers_list(frame.columns.values, dims)
else:
header_list = EclSum._compile_headers_list(headers, dims)
if dims is None:
dims = [1, 1, 1]
ecl_sum = EclSum.writer(
case, start_time.to_pydatetime(), dims[0], dims[1], dims[2]
)
ecl_sum = EclSum.writer(case, start_time, dims[0], dims[1], dims[2])
for kw, wgname, num, unit in header_list:
var_list.append(
ecl_sum.addVariable(kw, wgname=wgname, num=num, unit=unit).getKey1()
Expand Down
24 changes: 24 additions & 0 deletions python/tests/ecl_tests/test_ecl_sum.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env python
import datetime
import os.path
import pandas as pd
import numpy as np

from cwrap import CFILE
from cwrap import Prototype, load, open as copen
Expand All @@ -19,6 +21,28 @@ def test_write_repr():
)


def test_that_year2263_through_pandas_works():
"""Date 2262-04-11 is the upper limit for nanosecond 64-bit
timestamps, which is what pandas<2 prefers.
"""
eclsum = EclSum.from_pandas(
"TESTCASE",
pd.DataFrame(
[
{"DATE": datetime.date(2000, 1, 1), "FPR": 200},
{"DATE": datetime.date(2263, 1, 1), "FPR": 1},
]
).set_index("DATE"),
)
assert eclsum.numpy_dates[0] == np.datetime64("2000-01-01T00:00:00.000")

# (This is hit by a round-off error due to 32-bit floats):
assert eclsum.numpy_dates[1] == np.datetime64("2262-12-31T23:57:52.000")

# Roundtrip:
assert eclsum.pandas_frame().index[1] == datetime.datetime(2262, 12, 31, 23, 57, 52)


@equinor_test()
class EclSumTest(EclTest):
def setUp(self):
Expand Down

0 comments on commit bfd3574

Please sign in to comment.