Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8bf57cb

Browse files
committed
Convert NaN values to None in numpy arrays.
This allows the default JSON encoder to do serialize panda dataframes
1 parent f12063c commit 8bf57cb

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

influxdb/influxdb08/dataframe_client.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,17 @@ class DataFrameClient(InfluxDBClient):
1515
The client reads and writes from pandas DataFrames.
1616
"""
1717

18-
def __init__(self, *args, **kwargs):
18+
def __init__(self, ignore_nan=True, *args, **kwargs):
1919
super(DataFrameClient, self).__init__(*args, **kwargs)
20+
2021
try:
2122
global pd
2223
import pandas as pd
2324
except ImportError as ex:
24-
raise ImportError(
25-
'DataFrameClient requires Pandas, "{ex}" problem importing'
26-
.format(ex=str(ex))
27-
)
28-
25+
raise ImportError('DataFrameClient requires Pandas, '
26+
'"{ex}" problem importing'.format(ex=str(ex)))
2927
self.EPOCH = pd.Timestamp('1970-01-01 00:00:00.000+00:00')
28+
self.ignore_nan = ignore_nan
3029

3130
def write_points(self, data, *args, **kwargs):
3231
"""
@@ -135,9 +134,24 @@ def _convert_dataframe_to_json(self, dataframe, name, time_precision='s'):
135134
for dt in dataframe.index]
136135
data = {'name': name,
137136
'columns': [str(column) for column in dataframe.columns],
138-
'points': list([list(x) for x in dataframe.values])}
137+
'points': [self._convert_array(x) for x in dataframe.values]}
139138
return data
140139

140+
def _convert_array(self, array):
141+
try:
142+
global np
143+
import numpy as np
144+
except ImportError as ex:
145+
raise ImportError('DataFrameClient requires Numpy, '
146+
'"{ex}" problem importing'.format(ex=str(ex)))
147+
if self.ignore_nan:
148+
number_types = (int, float, np.number)
149+
condition = (all(isinstance(el, number_types) for el in array) and
150+
np.isnan(array))
151+
return list(np.where(condition, None, array))
152+
else:
153+
return list(array)
154+
141155
def _datetime_to_epoch(self, datetime, time_precision='s'):
142156
seconds = (datetime - self.EPOCH).total_seconds()
143157
if time_precision == 's':

tests/influxdb/influxdb08/dataframe_client_test.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,32 @@ def test_write_points_from_dataframe(self):
5252

5353
self.assertListEqual(json.loads(m.last_request.body), points)
5454

55+
def test_write_points_from_dataframe_with_float_nan(self):
56+
now = pd.Timestamp('1970-01-01 00:00+00:00')
57+
dataframe = pd.DataFrame(data=[[1, float("NaN"), 1.0], [2, 2, 2.0]],
58+
index=[now, now + timedelta(hours=1)],
59+
columns=["column_one", "column_two",
60+
"column_three"])
61+
points = [
62+
{
63+
"points": [
64+
[1, None, 1.0, 0],
65+
[2, 2, 2.0, 3600]
66+
],
67+
"name": "foo",
68+
"columns": ["column_one", "column_two", "column_three", "time"]
69+
}
70+
]
71+
72+
with requests_mock.Mocker() as m:
73+
m.register_uri(requests_mock.POST,
74+
"http://localhost:8086/db/db/series")
75+
76+
cli = DataFrameClient(database='db')
77+
cli.write_points({"foo": dataframe})
78+
79+
self.assertListEqual(json.loads(m.last_request.body), points)
80+
5581
def test_write_points_from_dataframe_in_batches(self):
5682
now = pd.Timestamp('1970-01-01 00:00+00:00')
5783
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],

0 commit comments

Comments
 (0)