Skip to content

Commit 93fd38b

Browse files
committed
make release-tag: Merge branch 'master' into stable
2 parents 9deb03a + 2a8766f commit 93fd38b

File tree

12 files changed

+227
-42
lines changed

12 files changed

+227
-42
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Latest Dependency Checker
2+
on:
3+
schedule:
4+
- cron: '0 * * * *'
5+
workflow_dispatch:
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- name: Set up Python 3.8
12+
uses: actions/setup-python@v2
13+
with:
14+
python-version: 3.8
15+
- name: Update dependencies
16+
run: |
17+
python -m pip install --upgrade pip
18+
python -m pip install -e .[test]
19+
make checkdeps OUTPUT_PATH=tests/requirement_files/latest_requirements.txt
20+
- name: Create pull request
21+
uses: peter-evans/create-pull-request@v3
22+
with:
23+
token: ${{ secrets.REPO_SCOPED_TOKEN }}
24+
commit-message: Update latest dependencies
25+
title: Automated Latest Dependency Updates
26+
body: "This is an auto-generated PR with **latest** dependency updates."
27+
branch: latest-dep-update
28+
branch-suffix: short-commit-hash
29+
base: master
30+
team-reviewers: core

.github/workflows/tests.yml

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,82 @@
11
name: Run Tests
22

33
on:
4-
- push
5-
- pull_request
4+
push:
5+
branches: [ '*' ]
6+
pull_request:
7+
branches: [ master ]
68

79
jobs:
8-
build:
10+
lint:
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
matrix:
14+
python-version: [3.8]
15+
os: [ubuntu-latest, macos-latest, windows-latest]
16+
steps:
17+
- uses: actions/checkout@v1
18+
- name: Set up Python ${{ matrix.python-version }}
19+
uses: actions/setup-python@v2
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
- name: Install package
23+
run: pip install invoke .[dev]
24+
- name: invoke lint
25+
run: invoke lint
26+
27+
28+
docs:
929
runs-on: ${{ matrix.os }}
1030
strategy:
1131
matrix:
1232
python-version: [3.6, 3.7, 3.8]
13-
os: [ubuntu-latest, macos-latest]
33+
os: [ubuntu-20.04]
34+
steps:
35+
- uses: actions/checkout@v1
36+
- name: Set up Python ${{ matrix.python-version }}
37+
uses: actions/setup-python@v2
38+
with:
39+
python-version: ${{ matrix.python-version }}
40+
- name: Install package
41+
run: pip install .[dev]
42+
- name: make docs
43+
run: make docs
1444

45+
46+
unit:
47+
runs-on: ${{ matrix.os }}
48+
strategy:
49+
matrix:
50+
python-version: [3.6, 3.7, 3.8]
51+
os: [ubuntu-20.04, macos-latest, windows-latest]
1552
steps:
1653
- uses: actions/checkout@v1
1754
- name: Set up Python ${{ matrix.python-version }}
18-
uses: actions/setup-python@v1
55+
uses: actions/setup-python@v2
1956
with:
2057
python-version: ${{ matrix.python-version }}
58+
- if: matrix.os == 'windows-latest' && matrix.python-version == 3.6
59+
name: Install dependencies - Windows with Python 3.6
60+
run: python -m pip install pywinpty==2.0.1
61+
- name: Install package and dependencies
62+
run: pip install invoke .[test]
63+
- name: invoke pytest
64+
run: invoke pytest
2165

22-
- name: Install dependencies
23-
run: |
24-
python -m pip install --upgrade pip
25-
pip install tox tox-gh-actions
2666

27-
- name: Test with tox
28-
run: tox
67+
minimum:
68+
runs-on: ${{ matrix.os }}
69+
strategy:
70+
matrix:
71+
python-version: [3.6, 3.7, 3.8]
72+
os: [ubuntu-20.04, macos-latest]
73+
steps:
74+
- uses: actions/checkout@v1
75+
- name: Set up Python ${{ matrix.python-version }}
76+
uses: actions/setup-python@v2
77+
with:
78+
python-version: ${{ matrix.python-version }}
79+
- name: Install package and dependencies
80+
run: pip install invoke .[test]
81+
- name: invoke minimum
82+
run: invoke minimum

DEVELOPMENT.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,12 @@ imported and used like this:
259259
from sigpro.demo import get_amplitude_demo
260260
from sigpro.demo import get_frequency_demo
261261
from sigpro.demo import get_frequency_time_demo
262+
from sigpro.demo import get_demo_data
262263

263264
amplitude_values, sampling_frequency = get_amplitude_demo()
264265
amplitude_values, frequency_values = get_frequency_demo()
265266
amplitude_values, frequency_values, time_values = get_frequency_time_demo()
266-
dataframe = get_frequency_time_demo(dataframe=True)
267+
dataframe = get_demo_data()
267268
```
268269

269270
In all cases, the functions will return values that correspond to a

HISTORY.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# History
22

3+
## 0.1.1 - 2023-04-06
4+
5+
### Features
6+
* Accepting single value data frame format - [Issue #36](https://github.com/sintel-dev/SigPro/issues/36) by @frances-h @sarahmish
7+
* Update demos - [Issue #26](https://github.com/sintel-dev/SigPro/pull/26) by @frances-h
8+
9+
## 0.1.0 - 2021-11-14
10+
11+
### Features
12+
* Rework SigPro to be class based
13+
314
## 0.0.3 - 2021-09-27
415

516
### Features

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,8 @@ release-minor: check-release bumpversion-minor release
255255

256256
.PHONY: release-major
257257
release-major: check-release bumpversion-major release
258+
259+
.PHONY: checkdeps
260+
checkdeps: # Save the currently installed versions of the dependencies as the latest versions
261+
$(eval allow_list='mlblocks|pandas|numpy|psutil')
262+
pip freeze | grep -v "sintel-dev/SigPro.git" | grep -E $(allow_list) > $(OUTPUT_PATH)

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.1.0
2+
current_version = 0.1.1.dev0
33
commit = True
44
tag = True
55
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<candidate>\d+))?

setup.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
history = history_file.read()
1313

1414
install_requires = [
15-
'mlblocks>=0.4.1,<0.5',
16-
'pandas>=1,<2',
17-
'numpy>=1.17.4,<1.19',
18-
'scipy>=1.3.3,<2',
15+
'mlblocks>=0.4.1',
16+
'pandas>=1',
17+
'numpy>=1.17.4',
18+
'scipy>=1.3.3',
1919
]
2020

2121
setup_requires = [
@@ -40,6 +40,8 @@
4040
'Sphinx>=1.7.1,<3',
4141
'sphinx_rtd_theme>=0.2.4,<0.5',
4242
'autodocsumm>=0.1.10',
43+
'markupsafe<2.1.0',
44+
'Jinja2>=2,<3',
4345

4446
# style check
4547
'flake8>=3.7.7,<4',
@@ -100,6 +102,6 @@
100102
test_suite='tests',
101103
tests_require=tests_require,
102104
url='https://github.com/sintel-dev/SigPro',
103-
version='0.1.0',
105+
version='0.1.1.dev0',
104106
zip_safe=False,
105107
)

sigpro/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
__author__ = """MIT Data To AI Lab"""
66
__email__ = '[email protected]'
7-
__version__ = '0.1.0'
7+
__version__ = '0.1.1.dev0'
88

99
import os
1010

sigpro/core.py

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,28 @@ def __init__(self, transformations, aggregations, values_column_name='values',
163163
self.input_is_dataframe = input_is_dataframe
164164
self.pipeline = self._build_pipeline()
165165

166-
def _apply_pipeline(self, row):
166+
def _apply_pipeline(self, window, is_series=False):
167167
"""Apply a ``mlblocks.MLPipeline`` to a row.
168168
169-
Apply a ``MLPipeline`` to a row of a ``pd.DataFrame``, this function can
169+
Apply a ``MLPipeline`` to a window of a ``pd.DataFrame``, this function can
170170
be combined with the ``pd.DataFrame.apply`` method to be applied to the
171171
entire data frame.
172172
173173
Args:
174-
row (pd.Series):
175-
Row used to apply the pipeline to.
174+
window (pd.Series):
175+
Row or multiple rows (window) used to apply the pipeline to.
176+
is_series (bool):
177+
Indicator whether window is formated as a series or dataframe.
176178
"""
177-
context = row.to_dict()
178-
amplitude_values = context.pop(self.values_column_name)
179+
if is_series:
180+
context = window.to_dict()
181+
amplitude_values = context.pop(self.values_column_name)
182+
else:
183+
context = {} if window.empty else {
184+
k: v for k, v in window.iloc[0].to_dict().items() if k != self.values_column_name
185+
}
186+
amplitude_values = list(window[self.values_column_name])
187+
179188
output = self.pipeline.predict(
180189
amplitude_values=amplitude_values,
181190
**context,
@@ -187,12 +196,19 @@ def _apply_pipeline(self, row):
187196

188197
return pd.Series(dict(zip(output_names, output)))
189198

190-
def process_signal(self, data=None, feature_columns=None, **kwargs):
199+
def process_signal(self, data=None, window=None, time_index=None, groupby_index=None,
200+
feature_columns=None, **kwargs):
191201
"""Apply multiple transformation and aggregation primitives.
192202
193203
Args:
194204
data (pandas.DataFrame):
195205
Dataframe with a column that contains signal values.
206+
window (str):
207+
Duration of window size, e.g. ('1h').
208+
time_index (str):
209+
Column in ``data`` that represents the time index.
210+
groupby_index (str or list[str]):
211+
Column(s) to group together and take the window over.
196212
feature_columns (list):
197213
List of column names from the input data frame that must be considered as
198214
features and should not be dropped.
@@ -207,15 +223,25 @@ def process_signal(self, data=None, feature_columns=None, **kwargs):
207223
A list with the feature names generated.
208224
"""
209225
if data is None:
210-
row = pd.Series(kwargs)
211-
values = self._apply_pipeline(row).values
226+
window = pd.Series(kwargs)
227+
values = self._apply_pipeline(window, is_series=True).values
212228
return values if len(values) > 1 else values[0]
213229

214-
features = data.apply(
215-
self._apply_pipeline,
216-
axis=1
217-
)
218-
data = pd.concat([data, features], axis=1)
230+
data = data.copy()
231+
if window is not None and groupby_index is not None:
232+
features = data.set_index(time_index).groupby(groupby_index).resample(
233+
rule=window, **kwargs).apply(
234+
self._apply_pipeline
235+
).reset_index()
236+
data = features
237+
238+
else:
239+
features = data.apply(
240+
self._apply_pipeline,
241+
axis=1,
242+
is_series=True
243+
)
244+
data = pd.concat([data, features], axis=1)
219245

220246
if feature_columns:
221247
feature_columns = feature_columns + list(features.columns)

sigpro/demo.py

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,60 @@
1111
DEMO_PATH = os.path.join(os.path.dirname(__file__), 'data')
1212

1313

14+
def _load_demo(nrows=None):
15+
demo_path = os.path.join(DEMO_PATH, 'demo_timeseries.csv')
16+
df = pd.read_csv(demo_path, parse_dates=['timestamp'], nrows=nrows)
17+
df['sampling_frequency'] = 1000
18+
df["values"] = df["values"].apply(json.loads).apply(list)
19+
20+
return df
21+
22+
1423
def get_demo_data(nrows=None):
1524
"""Get a demo ``pandas.DataFrame`` containing the accepted data format.
1625
26+
Args:
27+
nrows (int):
28+
Number of rows to load from the demo datasets.
29+
1730
Returns:
1831
A ``pd.DataFrame`` containing as ``values`` the signal values.
1932
"""
20-
demo_path = os.path.join(DEMO_PATH, 'demo_timeseries.csv')
21-
df = pd.read_csv(demo_path, parse_dates=['timestamp'], nrows=nrows)
22-
df["values"] = df["values"].apply(json.loads).apply(list)
33+
df = _load_demo(nrows)
34+
df = df.explode('values').reset_index(drop=True)
35+
36+
time_delta = pd.to_timedelta(list(range(400)) * 750, 's')
37+
df['timestamp'] = df['timestamp'] + time_delta
2338
return df
2439

2540

41+
def get_demo_primitives():
42+
"""Get a dict of demo transformation and aggregation primitives.
43+
44+
Returns:
45+
A tuple containing the list of transformation primitives and
46+
the list aggregation primitives
47+
"""
48+
transformations = [
49+
{
50+
"name": "fft",
51+
"primitive": "sigpro.transformations.frequency.fft.fft"
52+
}
53+
]
54+
aggregations = [
55+
{
56+
"name": "mean",
57+
"primitive": "sigpro.aggregations.amplitude.statistical.mean"
58+
},
59+
{
60+
"name": "std",
61+
"primitive": "sigpro.aggregations.amplitude.statistical.std"
62+
}
63+
]
64+
65+
return transformations, aggregations
66+
67+
2668
def get_amplitude_demo(index=None):
2769
"""Get amplitude values and sampling frequency used.
2870
@@ -43,7 +85,7 @@ def get_amplitude_demo(index=None):
4385
A tuple with a `np.array` containing amplitude values and as second element the
4486
sampling frequency used.
4587
"""
46-
df = get_demo_data()
88+
df = _load_demo()
4789
if index is None:
4890
index = random.randint(0, len(df))
4991

0 commit comments

Comments
 (0)