Skip to content

Commit bb8e665

Browse files
committed
fix: Fixed serialization of DataFrame with empty values #118
1 parent 1bb088f commit bb8e665

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
### Bug Fixes
88
1. [#117](https://github.com/influxdata/influxdb-client-python/pull/117): Fixed appending default tags for single Point
9+
1. [#118](https://github.com/influxdata/influxdb-client-python/issues/118): Fixed serialization of DataFrame with empty values
910

1011
## 1.8.0 [2020-06-19]
1112

influxdb_client/client/write_api.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# coding: utf-8
22
import logging
33
import os
4+
import re
45
from collections import defaultdict
56
from datetime import timedelta
67
from enum import Enum
8+
from functools import reduce
9+
from itertools import chain
710
from random import random
811
from time import sleep
912
from typing import Union, List, Any
@@ -307,6 +310,20 @@ def _itertuples(self, data_frame):
307310
cols = [data_frame.iloc[:, k] for k in range(len(data_frame.columns))]
308311
return zip(data_frame.index, *cols)
309312

313+
def _replace(self, data_frame):
314+
from ..extras import np
315+
obj_cols = {k for k, v in dict(data_frame.dtypes).items() if v is np.dtype('O')}
316+
other_cols = set(data_frame.columns) - obj_cols
317+
obj_nans = (f'{k}="nan"' for k in obj_cols)
318+
other_nans = (f'{k}=nani?' for k in other_cols)
319+
replacements = [
320+
('|'.join(chain(obj_nans, other_nans)), ''),
321+
(',{2,}', ','),
322+
('|'.join([', ,', ', ', ' ,']), ' '),
323+
]
324+
325+
return replacements
326+
310327
def _data_frame_to_list_of_points(self, data_frame, precision, **kwargs):
311328
from ..extras import pd, np
312329
if not isinstance(data_frame, pd.DataFrame):
@@ -352,7 +369,16 @@ def _data_frame_to_list_of_points(self, data_frame, precision, **kwargs):
352369
' ', ','.join(fields), ' {p[0].value}')
353370
f = eval("lambda p: f'{}'".format(''.join(fmt)))
354371

355-
return list(map(f, self._itertuples(data_frame)))
372+
isnull = data_frame.isnull().any(axis=1)
373+
374+
if isnull.any():
375+
lp = map(f, self._itertuples(data_frame[~isnull]))
376+
rep = self._replace(data_frame)
377+
lp_nan = (reduce(lambda a, b: re.sub(*b, a), rep, f(p))
378+
for p in self._itertuples(data_frame[isnull]))
379+
return list(chain(lp, lp_nan))
380+
else:
381+
return list(map(f, self._itertuples(data_frame)))
356382

357383
def _http(self, batch_item: _BatchItem):
358384

tests/test_WriteApiDataFrame.py

+29
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,32 @@ def test_write_num_py(self):
8686
self.assertEqual(result[0].records[1].get_value(), 200.0)
8787

8888
pass
89+
90+
def test_write_nan(self):
91+
from influxdb_client.extras import pd, np
92+
93+
now = pd.Timestamp('2020-04-05 00:00+00:00')
94+
95+
data_frame = pd.DataFrame(data=[[3.1955, np.nan, 20.514305, np.nan],
96+
[5.7310, np.nan, 23.328710, np.nan],
97+
[np.nan, 3.138664, np.nan, 20.755026],
98+
[np.nan, 5.139563, np.nan, 19.791240]],
99+
index=[now, now + timedelta(minutes=30), now + timedelta(minutes=60),
100+
now + timedelta(minutes=90)],
101+
columns=["actual_kw_price", "forecast_kw_price", "actual_general_use",
102+
"forecast_general_use"])
103+
104+
points = self.client.write_api(write_options=SYNCHRONOUS)\
105+
._data_frame_to_list_of_points(data_frame=data_frame,
106+
precision=None,
107+
data_frame_measurement_name='measurement')
108+
109+
self.assertEqual(4, len(points))
110+
self.assertEqual("measurement actual_kw_price=3.1955,actual_general_use=20.514305 1586044800000000000",
111+
points[0])
112+
self.assertEqual("measurement actual_kw_price=5.731,actual_general_use=23.32871 1586046600000000000",
113+
points[1])
114+
self.assertEqual("measurement forecast_kw_price=3.138664,forecast_general_use=20.755026 1586048400000000000",
115+
points[2])
116+
self.assertEqual("measurement forecast_kw_price=5.139563,forecast_general_use=19.79124 1586050200000000000",
117+
points[3])

0 commit comments

Comments
 (0)