scdata 1.0.0__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {scdata-1.0.0/scdata.egg-info → scdata-1.0.1}/PKG-INFO +4 -6
  2. {scdata-1.0.0 → scdata-1.0.1}/README.md +3 -5
  3. {scdata-1.0.0 → scdata-1.0.1}/scdata/__init__.py +1 -1
  4. {scdata-1.0.0 → scdata-1.0.1}/scdata/io/device_file.py +1 -1
  5. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/plot_tools.py +37 -16
  6. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_dispersion_uplot.py +1 -1
  7. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_uplot.py +1 -1
  8. scdata-1.0.1/scdata/test/tools/combine.py +64 -0
  9. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/units.py +1 -1
  10. {scdata-1.0.0 → scdata-1.0.1/scdata.egg-info}/PKG-INFO +4 -6
  11. {scdata-1.0.0 → scdata-1.0.1}/setup.py +1 -1
  12. scdata-1.0.0/scdata/test/tools/combine.py +0 -60
  13. {scdata-1.0.0 → scdata-1.0.1}/LICENSE +0 -0
  14. {scdata-1.0.0 → scdata-1.0.1}/MANIFEST.in +0 -0
  15. {scdata-1.0.0 → scdata-1.0.1}/requirements.txt +0 -0
  16. {scdata-1.0.0 → scdata-1.0.1}/scdata/_config/__init__.py +0 -0
  17. {scdata-1.0.0 → scdata-1.0.1}/scdata/_config/config.py +0 -0
  18. {scdata-1.0.0 → scdata-1.0.1}/scdata/_config/custom_logger.py +0 -0
  19. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/__init__.py +0 -0
  20. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/device.py +0 -0
  21. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/__init__.py +0 -0
  22. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/alphasense.py +0 -0
  23. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/baseline.py +0 -0
  24. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/formulae.py +0 -0
  25. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/geoseries.py +0 -0
  26. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/params.py +0 -0
  27. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/regression.py +0 -0
  28. {scdata-1.0.0 → scdata-1.0.1}/scdata/device/process/timeseries.py +0 -0
  29. {scdata-1.0.0 → scdata-1.0.1}/scdata/io/__init__.py +0 -0
  30. {scdata-1.0.0 → scdata-1.0.1}/scdata/io/device_api.py +0 -0
  31. {scdata-1.0.0 → scdata-1.0.1}/scdata/io/model.py +0 -0
  32. {scdata-1.0.0 → scdata-1.0.1}/scdata/models/__init__.py +0 -0
  33. {scdata-1.0.0 → scdata-1.0.1}/scdata/models/models.py +0 -0
  34. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/__init__.py +0 -0
  35. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/checks/__init__.py +0 -0
  36. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/checks/checks.py +0 -0
  37. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/dispersion/__init__.py +0 -0
  38. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/dispersion/dispersion.py +0 -0
  39. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/export/__init__.py +0 -0
  40. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/export/templates/sc_template.html +0 -0
  41. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/export/to_file.py +0 -0
  42. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/__init__.py +0 -0
  43. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/box_plot.py +0 -0
  44. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/heatmap_iplot.py +0 -0
  45. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/heatmap_plot.py +0 -0
  46. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/maps.py +0 -0
  47. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/scatter_dispersion_grid.py +0 -0
  48. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/scatter_iplot.py +0 -0
  49. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/scatter_plot.py +0 -0
  50. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/target_diagram.py +0 -0
  51. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_dendrogram.py +0 -0
  52. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_dispersion_grid.py +0 -0
  53. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_dispersion_plot.py +0 -0
  54. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_iplot.py +0 -0
  55. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_plot.py +0 -0
  56. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/plot/ts_scatter.py +0 -0
  57. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/test.py +0 -0
  58. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/tools/__init__.py +0 -0
  59. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/tools/history.py +0 -0
  60. {scdata-1.0.0 → scdata-1.0.1}/scdata/test/tools/prepare.py +0 -0
  61. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/__init__.py +0 -0
  62. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/cleaning.py +0 -0
  63. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/custom_logger.py +0 -0
  64. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/date.py +0 -0
  65. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/dictmerge.py +0 -0
  66. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/find.py +0 -0
  67. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/gets.py +0 -0
  68. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/interim/example.csv +0 -0
  69. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/interim/geodata.csv +0 -0
  70. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/lazy.py +0 -0
  71. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/location.py +0 -0
  72. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/report.py +0 -0
  73. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/stats.py +0 -0
  74. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/uploads/example_upload_1.json +0 -0
  75. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/uploads/example_zenodo_upload.yaml +0 -0
  76. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/uploads/report.pdf +0 -0
  77. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/url_check.py +0 -0
  78. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/zenodo.py +0 -0
  79. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/zenodo_templates/README.md +0 -0
  80. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/zenodo_templates/template_zenodo_dataset.json +0 -0
  81. {scdata-1.0.0 → scdata-1.0.1}/scdata/tools/zenodo_templates/template_zenodo_publication.json +0 -0
  82. {scdata-1.0.0 → scdata-1.0.1}/scdata.egg-info/SOURCES.txt +0 -0
  83. {scdata-1.0.0 → scdata-1.0.1}/scdata.egg-info/dependency_links.txt +0 -0
  84. {scdata-1.0.0 → scdata-1.0.1}/scdata.egg-info/not-zip-safe +0 -0
  85. {scdata-1.0.0 → scdata-1.0.1}/scdata.egg-info/requires.txt +0 -0
  86. {scdata-1.0.0 → scdata-1.0.1}/scdata.egg-info/top_level.txt +0 -0
  87. {scdata-1.0.0 → scdata-1.0.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scdata
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Analysis of sensors and time series data
5
5
  Home-page: https://github.com/fablabbcn/smartcitizen-data
6
6
  Author: oscgonfer
@@ -46,21 +46,19 @@ Smart Citizen Data
46
46
  [![DOI](https://zenodo.org/badge/97752018.svg)](https://zenodo.org/badge/latestdoi/97752018)
47
47
  [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks)
48
48
  [![PyPI version](https://badge.fury.io/py/scdata.svg)](https://badge.fury.io/py/scdata)
49
- [![Python application](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-app.yml/badge.svg)](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-app.yml)
49
+ [![Python application](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-multiple-versions.yml/badge.svg)](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-multiple-versions.yml)
50
50
 
51
51
  Welcome to **SmartCitizen Data**. This is a data analysis framework for working with sensor data in different ways:
52
52
 
53
53
  - Interacting with several sensors APIs
54
54
  - Clean data, export and calculate metrics
55
55
  - Model sensor data and calibrate sensors
56
- - Generate data visualisations - matplotlib, [plotly](https://plotly.com/) or [uplot](https://leeoniya.github.io/uPlot)
56
+ - Generate data visualisations - matplotlib, ~[plotly](https://plotly.com/)~ or [uplot](https://leeoniya.github.io/uPlot)
57
57
  - Generate analysis reports in html or pdf and upload them to [Zenodo](http://zenodo.org)
58
58
 
59
- A full documentation of the framework is detailed in [the Smart Citizen Docs](https://docs.smartcitizen.me/Data/Data%20Analysis/).
60
-
61
59
  ## Installation
62
60
 
63
- You can check it out in the [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks) before installing if you want. Works with `Python 3.*` (tested until `python 3.9.5`).
61
+ You can check it out in the [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks) before installing if you want. Works with `Python 3.*` (tested between 3.9 and 3.11).
64
62
 
65
63
  You can just run:
66
64
 
@@ -4,21 +4,19 @@ Smart Citizen Data
4
4
  [![DOI](https://zenodo.org/badge/97752018.svg)](https://zenodo.org/badge/latestdoi/97752018)
5
5
  [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks)
6
6
  [![PyPI version](https://badge.fury.io/py/scdata.svg)](https://badge.fury.io/py/scdata)
7
- [![Python application](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-app.yml/badge.svg)](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-app.yml)
7
+ [![Python application](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-multiple-versions.yml/badge.svg)](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-multiple-versions.yml)
8
8
 
9
9
  Welcome to **SmartCitizen Data**. This is a data analysis framework for working with sensor data in different ways:
10
10
 
11
11
  - Interacting with several sensors APIs
12
12
  - Clean data, export and calculate metrics
13
13
  - Model sensor data and calibrate sensors
14
- - Generate data visualisations - matplotlib, [plotly](https://plotly.com/) or [uplot](https://leeoniya.github.io/uPlot)
14
+ - Generate data visualisations - matplotlib, ~[plotly](https://plotly.com/)~ or [uplot](https://leeoniya.github.io/uPlot)
15
15
  - Generate analysis reports in html or pdf and upload them to [Zenodo](http://zenodo.org)
16
16
 
17
- A full documentation of the framework is detailed in [the Smart Citizen Docs](https://docs.smartcitizen.me/Data/Data%20Analysis/).
18
-
19
17
  ## Installation
20
18
 
21
- You can check it out in the [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks) before installing if you want. Works with `Python 3.*` (tested until `python 3.9.5`).
19
+ You can check it out in the [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks) before installing if you want. Works with `Python 3.*` (tested between 3.9 and 3.11).
22
20
 
23
21
  You can just run:
24
22
 
@@ -3,4 +3,4 @@ from .device import Device
3
3
  from .test import Test
4
4
  from .models import Source, TestOptions, DeviceOptions, APIParams, FileParams, CSVParams
5
5
 
6
- __version__ = '1.0.0'
6
+ __version__ = '1.0.1'
@@ -128,7 +128,7 @@ def read_csv_file(path, timezone, frequency=None, clean_na=None, index_name='',
128
128
 
129
129
  # Read pandas dataframe
130
130
 
131
- df = read_csv(path, verbose=False, skiprows=skiprows, sep=sep,
131
+ df = read_csv(path, skiprows=skiprows, sep=sep,
132
132
  encoding=encoding, encoding_errors='ignore')
133
133
 
134
134
  flag_found = False
@@ -93,14 +93,15 @@ def prepare_data(test, traces, options):
93
93
  logger.warning(f'The trace {traces[trace]} was not placed in any subplot. Assuming subplot #1')
94
94
  traces[trace]['subplot'] = 1
95
95
 
96
+
96
97
  ndevs = traces[trace]['devices']
97
98
  nchans = traces[trace]['channel']
98
99
 
99
100
  # Make them lists always
100
101
  if ndevs == 'all': devices = [device.id for device in test.devices]
102
+ ## TODO Make it regex compatible!
101
103
  elif type(ndevs) == str or type(ndevs) == int: devices = [ndevs]
102
104
  else: devices = ndevs
103
- print (devices)
104
105
 
105
106
  for ndev in devices:
106
107
 
@@ -158,8 +159,23 @@ def prepare_data(test, traces, options):
158
159
  # Remove column for filtering from dfdev
159
160
  dfdev.drop(columns=[col_name], inplace = True)
160
161
 
162
+ # Resample it
163
+ if options['frequency'] is not None:
164
+ logger.info(f"Resampling at {options['frequency']}")
165
+
166
+ if 'resample' in options:
167
+
168
+ if options['resample'] == 'max': dfdev = dfdev.resample(options['frequency']).max()
169
+ if options['resample'] == 'min': dfdev = dfdev.resample(options['frequency']).min()
170
+ if options['resample'] == 'mean': dfdev = dfdev.resample(options['frequency']).mean()
171
+
172
+ else:
173
+ dfdev = dfdev.resample(options['frequency']).mean()
174
+
161
175
  # Combine it in the df
162
176
  df = df.combine_first(dfdev)
177
+
178
+ ## TODO Is this working?
163
179
  # Add average or other extras
164
180
  # TODO Check this to simplify
165
181
  # https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.resample.Resampler.aggregate.html
@@ -168,15 +184,19 @@ def prepare_data(test, traces, options):
168
184
 
169
185
  nextras = list()
170
186
  for device in traces[trace]['devices']:
171
- for channel in traces[trace]['channel']:
172
- nextras.append(f'{channel}_{ndev}')
187
+ if type(traces[trace]['channel']) == 'list':
188
+ for channel in traces[trace]['channel']:
189
+ nextras.append(f'{channel}_{device}')
190
+ else:
191
+ nextras.append(f"{traces[trace]['channel']}_{device}")
173
192
 
174
193
  if extra == 'bands':
175
- ubn = channel + f"-{trace}-{'UPPER-BAND'}"
176
- lbn = channel + f"-{trace}-{'LOWER-BAND'}"
194
+ ubn = channel + f"-{trace}-UPPER-BAND"
195
+ lbn = channel + f"-{trace}-LOWER-BAND"
177
196
 
178
- df[ubn] = df.loc[:, nextras].mean(axis = 1) + 2*df.loc[:, nextras].std(axis = 1)
179
- df[lbn] = df.loc[:, nextras].mean(axis = 1) - 2*df.loc[:, nextras].std(axis = 1)
197
+ logger.info('Using 3sig bands')
198
+ df[ubn] = df.loc[:, nextras].mean(axis = 1) + 3*df.loc[:, nextras].std(axis = 1)
199
+ df[lbn] = df.loc[:, nextras].mean(axis = 1) - 3*df.loc[:, nextras].std(axis = 1)
180
200
 
181
201
  subplots[traces[trace]['subplot']-1].append(ubn)
182
202
  subplots[traces[trace]['subplot']-1].append(lbn)
@@ -208,18 +228,19 @@ def prepare_data(test, traces, options):
208
228
  if df.empty:
209
229
  logger.error('Empty dataframe for plot')
210
230
  return None, None
211
- # Resample it
212
- if options['frequency'] is not None:
213
- logger.info(f"Resampling at {options['frequency']}")
214
231
 
215
- if 'resample' in options:
232
+ # # Resample it
233
+ # if options['frequency'] is not None:
234
+ # logger.info(f"Resampling at {options['frequency']}")
216
235
 
217
- if options['resample'] == 'max': df = df.resample(options['frequency']).max()
218
- if options['resample'] == 'min': df = df.resample(options['frequency']).min()
219
- if options['resample'] == 'mean': df = df.resample(options['frequency']).mean()
236
+ # if 'resample' in options:
220
237
 
221
- else:
222
- df = df.resample(options['frequency']).mean()
238
+ # if options['resample'] == 'max': df = df.resample(options['frequency']).max()
239
+ # if options['resample'] == 'min': df = df.resample(options['frequency']).min()
240
+ # if options['resample'] == 'mean': df = df.resample(options['frequency']).mean()
241
+
242
+ # else:
243
+ # df = df.resample(options['frequency']).mean()
223
244
 
224
245
  # Clean na
225
246
  if options['clean_na'] is not None:
@@ -149,7 +149,7 @@ def ts_dispersion_uplot(self, **kwargs):
149
149
 
150
150
  if formatting['join_sbplot']: n_subplots = 1
151
151
  else: n_subplots = 2
152
- udf.index = udf.index.astype(int)/10**9
152
+ udf.index = udf.index.astype('int64')/10**9
153
153
 
154
154
  # Compose subplots lists
155
155
  for device in self.devices:
@@ -112,7 +112,7 @@ def ts_uplot(self, **kwargs):
112
112
 
113
113
  # Get data in uplot expected format
114
114
  udf = df.copy()
115
- udf.index = udf.index.astype(int)/10**9
115
+ udf.index = udf.index.astype('int64')/10**9
116
116
 
117
117
  for isbplt in range(n_subplots):
118
118
 
@@ -0,0 +1,64 @@
1
+ from pandas import DataFrame
2
+ from scdata.tools.custom_logger import logger
3
+ from scdata.device import Device
4
+
5
+ def combine(self, devices = None, channels = None, resample = True, frequency = '1Min'):
6
+ """
7
+ Combines devices from a test into a new dataframe, following the
8
+ naming as follows: DEVICE-NAME_READING-NAME
9
+ Parameters
10
+ ----------
11
+ devices: list or None
12
+ None
13
+ If None, includes all the devices in self.devices
14
+ channels: list or None
15
+ None
16
+ If None, includes all the readings in self.readings
17
+ Returns
18
+ -------
19
+ Dataframe if successful or False otherwise
20
+ """
21
+
22
+ dfc = DataFrame()
23
+ if not self.loaded:
24
+ logger.error('Cannot combine data if test is not loaded. Maybe test.load() first?')
25
+
26
+ if devices is None:
27
+ dl = [device.id for device in self.devices]
28
+ else:
29
+ # Only requested AND available
30
+ dl = list(set(devices).intersection([device.id for device in self.devices]))
31
+ if len(dl) != len(devices):
32
+ logger.warning('Requested devices are not all present in devices')
33
+ logger.info(f'Discarding {set(devices).difference([device.id for device in self.devices])}')
34
+
35
+ for device in dl:
36
+ new_names = list()
37
+
38
+ if channels is None:
39
+ channel_list = list(self.get_device(device).data.columns)
40
+ else:
41
+ # Only pick the ones that are actually present
42
+ channel_list = list(set(channels).intersection(list(self.get_device(device).data.columns)))
43
+
44
+ if any([channel not in channel_list for channel in channels]):
45
+ logger.warning(f'Requested channels are not all present in readings for device {device}')
46
+ logger.warning(f'Discarding {list(set(channels).difference(list(self.get_device(device).data.columns)))}')
47
+
48
+ rename = dict()
49
+
50
+ for channel in channel_list:
51
+ rename[channel] = f'{channel}_{self.get_device(device).id}'
52
+
53
+ df = self.get_device(device).data[channel_list].copy()
54
+ df.rename(columns = rename, inplace = True)
55
+ if resample:
56
+ df = df.resample(frequency).mean()
57
+ dfc = dfc.combine_first(df)
58
+
59
+ if dfc.empty:
60
+ logger.error('Error ocurred while combining data. Review data')
61
+ return False
62
+ else:
63
+ logger.info('Data combined successfully')
64
+ return dfc
@@ -92,7 +92,7 @@ def get_units_convf(sensor, from_units):
92
92
  else: molecular_weight = 1
93
93
 
94
94
  # Check if channel is in look-up table
95
- if channel_lut[channel] != from_units and from_units != "":
95
+ if channel_lut[channel] != from_units and from_units != "" and from_units is not None:
96
96
  logger.info(f"Converting units for {sensor}. From {from_units} to {channel_lut[channel]}")
97
97
  for unit in unit_convertion_lut:
98
98
  # Get units
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scdata
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Analysis of sensors and time series data
5
5
  Home-page: https://github.com/fablabbcn/smartcitizen-data
6
6
  Author: oscgonfer
@@ -46,21 +46,19 @@ Smart Citizen Data
46
46
  [![DOI](https://zenodo.org/badge/97752018.svg)](https://zenodo.org/badge/latestdoi/97752018)
47
47
  [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks)
48
48
  [![PyPI version](https://badge.fury.io/py/scdata.svg)](https://badge.fury.io/py/scdata)
49
- [![Python application](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-app.yml/badge.svg)](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-app.yml)
49
+ [![Python application](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-multiple-versions.yml/badge.svg)](https://github.com/fablabbcn/smartcitizen-data/actions/workflows/python-multiple-versions.yml)
50
50
 
51
51
  Welcome to **SmartCitizen Data**. This is a data analysis framework for working with sensor data in different ways:
52
52
 
53
53
  - Interacting with several sensors APIs
54
54
  - Clean data, export and calculate metrics
55
55
  - Model sensor data and calibrate sensors
56
- - Generate data visualisations - matplotlib, [plotly](https://plotly.com/) or [uplot](https://leeoniya.github.io/uPlot)
56
+ - Generate data visualisations - matplotlib, ~[plotly](https://plotly.com/)~ or [uplot](https://leeoniya.github.io/uPlot)
57
57
  - Generate analysis reports in html or pdf and upload them to [Zenodo](http://zenodo.org)
58
58
 
59
- A full documentation of the framework is detailed in [the Smart Citizen Docs](https://docs.smartcitizen.me/Data/Data%20Analysis/).
60
-
61
59
  ## Installation
62
60
 
63
- You can check it out in the [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks) before installing if you want. Works with `Python 3.*` (tested until `python 3.9.5`).
61
+ You can check it out in the [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/fablabbcn/smartcitizen-data-framework/master?filepath=%2Fexamples%2Fnotebooks) before installing if you want. Works with `Python 3.*` (tested between 3.9 and 3.11).
64
62
 
65
63
  You can just run:
66
64
 
@@ -19,7 +19,7 @@ REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]
19
19
 
20
20
  setup(
21
21
  name='scdata',
22
- version='1.0.0',
22
+ version='1.0.1',
23
23
  description='Analysis of sensors and time series data',
24
24
  author='oscgonfer',
25
25
  license='GNU-GPL3.0',
@@ -1,60 +0,0 @@
1
- from pandas import DataFrame
2
- from scdata.tools.custom_logger import logger
3
- from scdata.device import Device
4
-
5
- def combine(self, devices = None, readings = None):
6
- """
7
- Combines devices from a test into a new dataframe, following the
8
- naming as follows: DEVICE-NAME_READING-NAME
9
- Parameters
10
- ----------
11
- devices: list or None
12
- None
13
- If None, includes all the devices in self.devices
14
- readings: list or None
15
- None
16
- If None, includes all the readings in self.readings
17
- Returns
18
- -------
19
- Dataframe if successful or False otherwise
20
- """
21
-
22
- dfc = DataFrame()
23
-
24
- if devices is None:
25
- dl = list(self.devices.keys())
26
- else:
27
- # Only pick the ones that are actually present
28
- dl = list(set(devices).intersection(list(self.devices.keys())))
29
- if len(dl) != len(devices):
30
- logger.warning('Requested devices are not all present in devices')
31
- logger.info(f'Discarding {set(devices).difference(list(self.devices.keys()))}')
32
-
33
- for device in dl:
34
- new_names = list()
35
-
36
- if readings is None:
37
- rl = list(self.devices[device].readings.columns)
38
- else:
39
- # Only pick the ones that are actually present
40
- rl = list(set(readings).intersection(list(self.devices[device].readings.columns)))
41
-
42
- if any([reading not in rl for reading in readings]):
43
- logger.warning(f'Requested readings are not all present in readings for device {device}')
44
- logger.warning(f'Discarding {list(set(readings).difference(list(self.devices[device].readings.columns)))}')
45
-
46
- rename = dict()
47
-
48
- for reading in rl:
49
- rename[reading] = reading + '_' + self.devices[device].id
50
-
51
- df = self.devices[device].readings[rl].copy()
52
- df.rename(columns = rename, inplace = True)
53
- dfc = dfc.combine_first(df)
54
-
55
- if dfc.empty:
56
- logger.error('Error ocurred while combining data. Review data')
57
- return False
58
- else:
59
- logger.info('Data combined successfully')
60
- return dfc
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes