Skip to content

Commit

Permalink
Fix compatibility with Pandas 2
Browse files Browse the repository at this point in the history
The `line_terminator` parameter of `read_csv` was changed to
`lineterminator` in Pandas 1.5, and the old name was dropped entirely in
Pandas 2.
  • Loading branch information
QuLogic committed Feb 24, 2024
1 parent 9773fea commit a280531
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 12 deletions.
13 changes: 13 additions & 0 deletions devicely/_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Pandas 1/2 compatibility."""

try:
import importlib.metadata as importlib_metadata
except ModuleNotFoundError:
import importlib_metadata

_pd_version = importlib_metadata.version('pandas')
_pd_major = int(_pd_version.split('.')[0])
_have_pd_2 = _pd_major >= 2
# Pandas 1.5 renamed the `line_terminator` parameter of the `to_csv` method to
# `lineterminator` for consistency, and then Pandas 2 removed the old name.
_to_csv_line_terminator = 'lineterminator' if _have_pd_2 else 'line_terminator'
11 changes: 8 additions & 3 deletions devicely/empatica.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import numpy as np
import pandas as pd

from ._compat import _to_csv_line_terminator


class EmpaticaReader:
"""
Expand Down Expand Up @@ -155,7 +157,8 @@ def _write_signal(self, path, dataframe, signal_name):
[self.sample_freqs[signal_name]] * n_cols])
with open(path, 'w') as file:
np.savetxt(file, meta, fmt='%s', delimiter=', ', newline='\n')
dataframe.to_csv(file, index=None, header=None, line_terminator='\n')
dataframe.to_csv(file, index=None, header=None,
**{_to_csv_line_terminator: '\n'})

def _read_ibi(self, path):
try:
Expand All @@ -179,7 +182,8 @@ def _write_ibi(self, path):
file.write(f"{self.start_times['IBI'].value // 1e9}, IBI\n")
write_df = self.IBI.copy()
write_df.index = (write_df.index - self.start_times['IBI']).values.astype(int) / 1e9
write_df.to_csv(file, header=None, line_terminator='\n')
write_df.to_csv(file, header=None,
**{_to_csv_line_terminator: '\n'})

def _read_tags(self, path):
try:
Expand All @@ -200,7 +204,8 @@ def _read_tags(self, path):
def _write_tags(self, path):
if self.tags is not None:
tags_write_series = self.tags.map(lambda x: x.value / 1e9)
tags_write_series.to_csv(path, header=None, index=None, line_terminator='\n')
tags_write_series.to_csv(path, header=None, index=None,
**{_to_csv_line_terminator: '\n'})

def timeshift(self, shift='random'):
"""
Expand Down
8 changes: 6 additions & 2 deletions devicely/everion.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import numpy as np
import pandas as pd

from ._compat import _to_csv_line_terminator


class EverionReader:
"""
Read, timeshift and write data generated by Biovotion Everion.
Expand Down Expand Up @@ -240,7 +243,7 @@ def _convert_single_dataframe(self, dataframe, selected_tags=None):
if selected_tags is not None:
dataframe = dataframe[dataframe['tag'].isin(selected_tags)]

dataframe['time'] = dataframe['time'].map(lambda x: x.value) / 10**9
dataframe['time'] = dataframe['time'].astype(np.int64) / 10**9
timestamps_min_and_count = dataframe.groupby('time').agg(
count_min=pd.NamedAgg(column='count', aggfunc='min'),
count_range=pd.NamedAgg(
Expand Down Expand Up @@ -318,7 +321,8 @@ def _write_single_dataframe(self, dataframe, filepath):
writing_dataframe.loc[quality_col.index, 'values'] += ';' + quality_col
writing_dataframe.drop(columns=['quality'], inplace=True)

writing_dataframe.to_csv(filepath, index=None, line_terminator='\n')
writing_dataframe.to_csv(filepath, index=None,
**{_to_csv_line_terminator: '\n'})

def timeshift(self, shift='random'):
"""
Expand Down
14 changes: 10 additions & 4 deletions devicely/faros.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import pandas as pd
import pyedflib as edf

from ._compat import _to_csv_line_terminator


class FarosReader:
"""
Expand Down Expand Up @@ -220,10 +222,14 @@ def _write_to_directory(self, path):
with open(os.path.join(path, 'meta.json'), 'w') as meta_file:
json.dump(meta, meta_file)

self.ECG.to_csv(os.path.join(path, 'ECG.csv'), index=None, line_terminator='\n')
self.ACC.to_csv(os.path.join(path, 'ACC.csv'), index=None, line_terminator='\n')
self.Marker.to_csv(os.path.join(path, 'Marker.csv'), index=None, line_terminator='\n')
self.HRV.to_csv(os.path.join(path, 'HRV.csv'), index=None, line_terminator='\n')
self.ECG.to_csv(os.path.join(path, 'ECG.csv'), index=None,
**{_to_csv_line_terminator: '\n'})
self.ACC.to_csv(os.path.join(path, 'ACC.csv'), index=None,
**{_to_csv_line_terminator: '\n'})
self.Marker.to_csv(os.path.join(path, 'Marker.csv'), index=None,
**{_to_csv_line_terminator: '\n'})
self.HRV.to_csv(os.path.join(path, 'HRV.csv'), index=None,
**{_to_csv_line_terminator: '\n'})

def timeshift(self, shift='random'):
"""
Expand Down
5 changes: 4 additions & 1 deletion devicely/shimmer_plus.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import numpy as np
import pandas as pd

from ._compat import _to_csv_line_terminator


class ShimmerPlusReader:
"""
Expand Down Expand Up @@ -69,7 +71,8 @@ def write(self, path):

with open(path, 'w') as f:
f.write(f'"sep={self.delimiter}"\n')
write_df.to_csv(f, index=False, sep=self.delimiter, line_terminator=f"{self.delimiter}\n")
write_df.to_csv(f, index=False, sep=self.delimiter,
**{_to_csv_line_terminator: f"{self.delimiter}\n"})

def timeshift(self, shift='random'):
"""
Expand Down
5 changes: 4 additions & 1 deletion devicely/spacelabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import pandas as pd

from ._compat import _to_csv_line_terminator


class SpacelabsReader:
"""
Expand Down Expand Up @@ -147,7 +149,8 @@ def write(self, path):
printing_df.replace('-9999', '""', inplace=True)
printing_df.replace('-9998', '"EB"', inplace=True)
printing_df.replace('-9997', '"AB"', inplace=True)
printing_df.to_csv(file, header=None, index=None, quoting=csv.QUOTE_NONE, line_terminator='\n')
printing_df.to_csv(file, header=None, index=None, quoting=csv.QUOTE_NONE,
**{_to_csv_line_terminator: '\n'})

xml_node = ET.Element('XML')
xml_node.extend(self._dict_to_etree(self.metadata))
Expand Down
6 changes: 5 additions & 1 deletion devicely/time_stamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import pandas as pd

from ._compat import _to_csv_line_terminator


class TimeStampReader:
"""
Read, timeshift and write data generated by the Android app TimeStamp
Expand Down Expand Up @@ -45,7 +48,8 @@ def write(self, path):

df_to_write = self.data.reset_index()[['tag_number', 'time', 'tag']]
df_to_write.time = df_to_write.time.dt.strftime("%Y/%-m/%-d(%a)\u3000%H:%M:%S").str.lower()
df_to_write.to_csv(path, header=None, index=None, line_terminator='\n')
df_to_write.to_csv(path, header=None, index=None,
**{_to_csv_line_terminator: '\n'})

def timeshift(self, shift='random'):
"""
Expand Down

0 comments on commit a280531

Please sign in to comment.