Skip to content

Commit 9eb2244

Browse files
committed
Changed API from .add to .update
1 parent e063902 commit 9eb2244

3 files changed

Lines changed: 86 additions & 88 deletions

File tree

docs/Tutorial_Matrix_Profiles_For_Streaming_Data.ipynb

Lines changed: 59 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
"metadata": {},
137137
"outputs": [],
138138
"source": [
139-
"stream.add(t)"
139+
"stream.update(t)"
140140
]
141141
},
142142
{
@@ -154,7 +154,7 @@
154154
"source": [
155155
"for i in range(1000):\n",
156156
" t = np.random.rand()\n",
157-
" stream.add(t)"
157+
" stream.update(t)"
158158
]
159159
},
160160
{
@@ -209,7 +209,7 @@
209209
"# Incrementally add one new data point at a time and update the matrix profile\n",
210210
"for i in range(len(T_stream), len(T_full)):\n",
211211
" t = T_full[i]\n",
212-
" stream.add(t)"
212+
" stream.update(t)"
213213
]
214214
},
215215
{
@@ -229,9 +229,9 @@
229229
"metadata": {},
230230
"outputs": [],
231231
"source": [
232-
"npt.assert_almost_equal(stream.T, T_full)\n",
233-
"npt.assert_almost_equal(stream.P, P_full)\n",
234-
"npt.assert_almost_equal(stream.I, I_full)"
232+
"npt.assert_almost_equal(stream.T_, T_full)\n",
233+
"npt.assert_almost_equal(stream.P_, P_full)\n",
234+
"npt.assert_almost_equal(stream.I_, I_full)"
235235
]
236236
},
237237
{
@@ -254,8 +254,8 @@
254254
"name": "stdout",
255255
"output_type": "stream",
256256
"text": [
257-
"stumpy.stump: 382.0s\n",
258-
"stumpy.stumpi:, 2.7s\n"
257+
"stumpy.stump: 429.9s\n",
258+
"stumpy.stumpi:, 3.4s\n"
259259
]
260260
}
261261
],
@@ -277,7 +277,7 @@
277277
"stream = stumpy.stumpi(T_stream, m)\n",
278278
"for i in range(200, len(T_full)):\n",
279279
" t = T_full[i]\n",
280-
" stream.add(t)\n",
280+
" stream.update(t)\n",
281281
"stumpi_time = time.time() - start\n",
282282
"\n",
283283
"print(f\"stumpy.stump: {np.round(stump_time,1)}s\")\n",
@@ -442,7 +442,7 @@
442442
{
443443
"data": {
444444
"text/plain": [
445-
"[<matplotlib.lines.Line2D at 0x1a18c6c090>]"
445+
"[<matplotlib.lines.Line2D at 0x1a1d4d1e90>]"
446446
]
447447
},
448448
"execution_count": 14,
@@ -522,16 +522,16 @@
522522
"metadata": {},
523523
"outputs": [],
524524
"source": [
525-
"windows = [(stream.P, T_stream)]\n",
525+
"windows = [(stream.P_, T_stream)]\n",
526526
"P_max = -1\n",
527527
"for i in range(2000, len(T_full)):\n",
528528
" t = T_full[i]\n",
529-
" stream.add(t)\n",
529+
" stream.update(t)\n",
530530
" \n",
531531
" if i % 50 == 0:\n",
532-
" windows.append((stream.P, T_full[:i+1]))\n",
533-
" if stream.P.max() > P_max:\n",
534-
" P_max = stream.P.max()"
532+
" windows.append((stream.P_, T_full[:i+1]))\n",
533+
" if stream.P_.max() > P_max:\n",
534+
" P_max = stream.P_.max()"
535535
]
536536
},
537537
{
@@ -735,39 +735,39 @@
735735
"</style>\n",
736736
"\n",
737737
"<div class=\"animation\">\n",
738-
" <img id=\"_anim_imgc3a4f9a1789e4fdc98ca388bf870d399\">\n",
738+
" <img id=\"_anim_img5290f275905e41ef98e897687f2bf782\">\n",
739739
" <div class=\"anim-controls\">\n",
740-
" <input id=\"_anim_sliderc3a4f9a1789e4fdc98ca388bf870d399\" type=\"range\" class=\"anim-slider\"\n",
740+
" <input id=\"_anim_slider5290f275905e41ef98e897687f2bf782\" type=\"range\" class=\"anim-slider\"\n",
741741
" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\"\n",
742-
" oninput=\"animc3a4f9a1789e4fdc98ca388bf870d399.set_frame(parseInt(this.value));\"></input>\n",
742+
" oninput=\"anim5290f275905e41ef98e897687f2bf782.set_frame(parseInt(this.value));\"></input>\n",
743743
" <div class=\"anim-buttons\">\n",
744-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.slower()\"><i class=\"fa fa-minus\"></i></button>\n",
745-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.first_frame()\"><i class=\"fa fa-fast-backward\">\n",
744+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.slower()\"><i class=\"fa fa-minus\"></i></button>\n",
745+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.first_frame()\"><i class=\"fa fa-fast-backward\">\n",
746746
" </i></button>\n",
747-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.previous_frame()\">\n",
747+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.previous_frame()\">\n",
748748
" <i class=\"fa fa-step-backward\"></i></button>\n",
749-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.reverse_animation()\">\n",
749+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.reverse_animation()\">\n",
750750
" <i class=\"fa fa-play fa-flip-horizontal\"></i></button>\n",
751-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.pause_animation()\"><i class=\"fa fa-pause\">\n",
751+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.pause_animation()\"><i class=\"fa fa-pause\">\n",
752752
" </i></button>\n",
753-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.play_animation()\"><i class=\"fa fa-play\"></i>\n",
753+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.play_animation()\"><i class=\"fa fa-play\"></i>\n",
754754
" </button>\n",
755-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.next_frame()\"><i class=\"fa fa-step-forward\">\n",
755+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.next_frame()\"><i class=\"fa fa-step-forward\">\n",
756756
" </i></button>\n",
757-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.last_frame()\"><i class=\"fa fa-fast-forward\">\n",
757+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.last_frame()\"><i class=\"fa fa-fast-forward\">\n",
758758
" </i></button>\n",
759-
" <button onclick=\"animc3a4f9a1789e4fdc98ca388bf870d399.faster()\"><i class=\"fa fa-plus\"></i></button>\n",
759+
" <button onclick=\"anim5290f275905e41ef98e897687f2bf782.faster()\"><i class=\"fa fa-plus\"></i></button>\n",
760760
" </div>\n",
761-
" <form action=\"#n\" name=\"_anim_loop_selectc3a4f9a1789e4fdc98ca388bf870d399\" class=\"anim-state\">\n",
762-
" <input type=\"radio\" name=\"state\" value=\"once\" id=\"_anim_radio1_c3a4f9a1789e4fdc98ca388bf870d399\"\n",
761+
" <form action=\"#n\" name=\"_anim_loop_select5290f275905e41ef98e897687f2bf782\" class=\"anim-state\">\n",
762+
" <input type=\"radio\" name=\"state\" value=\"once\" id=\"_anim_radio1_5290f275905e41ef98e897687f2bf782\"\n",
763763
" checked>\n",
764-
" <label for=\"_anim_radio1_c3a4f9a1789e4fdc98ca388bf870d399\">Once</label>\n",
765-
" <input type=\"radio\" name=\"state\" value=\"loop\" id=\"_anim_radio2_c3a4f9a1789e4fdc98ca388bf870d399\"\n",
764+
" <label for=\"_anim_radio1_5290f275905e41ef98e897687f2bf782\">Once</label>\n",
765+
" <input type=\"radio\" name=\"state\" value=\"loop\" id=\"_anim_radio2_5290f275905e41ef98e897687f2bf782\"\n",
766766
" >\n",
767-
" <label for=\"_anim_radio2_c3a4f9a1789e4fdc98ca388bf870d399\">Loop</label>\n",
768-
" <input type=\"radio\" name=\"state\" value=\"reflect\" id=\"_anim_radio3_c3a4f9a1789e4fdc98ca388bf870d399\"\n",
767+
" <label for=\"_anim_radio2_5290f275905e41ef98e897687f2bf782\">Loop</label>\n",
768+
" <input type=\"radio\" name=\"state\" value=\"reflect\" id=\"_anim_radio3_5290f275905e41ef98e897687f2bf782\"\n",
769769
" >\n",
770-
" <label for=\"_anim_radio3_c3a4f9a1789e4fdc98ca388bf870d399\">Reflect</label>\n",
770+
" <label for=\"_anim_radio3_5290f275905e41ef98e897687f2bf782\">Reflect</label>\n",
771771
" </form>\n",
772772
" </div>\n",
773773
"</div>\n",
@@ -777,9 +777,9 @@
777777
" /* Instantiate the Animation class. */\n",
778778
" /* The IDs given should match those used in the template above. */\n",
779779
" (function() {\n",
780-
" var img_id = \"_anim_imgc3a4f9a1789e4fdc98ca388bf870d399\";\n",
781-
" var slider_id = \"_anim_sliderc3a4f9a1789e4fdc98ca388bf870d399\";\n",
782-
" var loop_select_id = \"_anim_loop_selectc3a4f9a1789e4fdc98ca388bf870d399\";\n",
780+
" var img_id = \"_anim_img5290f275905e41ef98e897687f2bf782\";\n",
781+
" var slider_id = \"_anim_slider5290f275905e41ef98e897687f2bf782\";\n",
782+
" var loop_select_id = \"_anim_loop_select5290f275905e41ef98e897687f2bf782\";\n",
783783
" var frames = new Array(153);\n",
784784
" \n",
785785
" frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAGwCAYAAABfOcJAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\\\n",
@@ -176798,7 +176798,7 @@
176798176798
" /* set a timeout to make sure all the above elements are created before\n",
176799176799
" the object is initialized. */\n",
176800176800
" setTimeout(function() {\n",
176801-
" animc3a4f9a1789e4fdc98ca388bf870d399 = new Animation(frames, img_id, slider_id, 100.0,\n",
176801+
" anim5290f275905e41ef98e897687f2bf782 = new Animation(frames, img_id, slider_id, 100.0,\n",
176802176802
" loop_select_id);\n",
176803176803
" }, 0);\n",
176804176804
" })()\n",
@@ -176891,22 +176891,22 @@
176891176891
"name": "stdout",
176892176892
"output_type": "stream",
176893176893
"text": [
176894-
"Full Matrix Profile: [1.47 1.52 1.75 1.91 1.71 1.52 1.24 1.52 1.75 1.29 1.87 1.44 1.61 2.26\n",
176895-
" 1.25 1.89 1.52 1.29 1.63 1.42 1.57 1.95 1.71 1.72 1.47 1.63 1.98 1.79\n",
176896-
" 1.25 1.98 1.86 2.28 2.01 1.47 1.74 1.24 1.84 2.1 1.57 1.95 1.47 1.74\n",
176897-
" 1.99 2.22 2.73 1.83 2.46 2.24 1.29 1.87 1.44 1.61 1.92 1.83 2.57 1.42\n",
176898-
" 2.49]\n",
176899-
"Left Matrix Profile: [ inf inf inf 4.21 3.52 3.7 1.69 1.52 1.75 1.91 2.61 3. 2.93 2.33\n",
176900-
" 2.11 2.26 1.52 1.29 1.92 2.31 2.3 2.19 1.71 1.72 1.47 1.63 2.19 1.79\n",
176901-
" 1.25 1.98 2.47 2.64 2.01 1.86 1.84 1.24 1.84 2.1 1.57 1.95 1.47 1.74\n",
176902-
" 1.99 2.22 2.73 2.46 2.46 2.24 1.29 1.87 1.44 1.61 1.92 1.83 2.57 1.42\n",
176903-
" 2.49]\n",
176904-
"Full Matrix Profile Indices: [24 7 8 9 22 16 35 1 2 48 49 50 51 52 28 22 5 6 25 55 38 39 4 5\n",
176905-
" 0 18 55 20 14 15 41 42 21 40 41 6 25 27 20 21 33 34 35 32 27 53 12 19\n",
176906-
" 9 10 11 12 7 45 29 19 53]\n",
176907-
"Left Matrix Profile Indices: [-1 -1 -1 0 1 2 0 1 2 3 4 5 6 1 9 4 5 6 7 8 2 14 4 5\n",
176908-
" 0 18 19 20 14 15 16 20 21 22 5 6 25 27 20 21 33 34 35 32 27 11 12 19\n",
176909-
" 9 10 11 12 7 45 29 19 53]\n"
176894+
"Full Matrix Profile: [2.59 2.56 2.4 2.07 1.99 2.22 2.18 1.57 2.29 1.8 1.94 1.93 1.97 2.12\n",
176895+
" 2.06 2.35 2.54 2.15 1.95 1.78 2.18 1.99 2.43 2.05 1.77 2.07 2.04 2.49\n",
176896+
" 2.18 2.23 1.57 1.68 1.59 1.93 1.68 1.59 2.12 2.12 1.77 1.78 2.08 2.06\n",
176897+
" 1.99 2.42 2.1 2.07 1.99 2.22 2.1 1.8 2.29 2.16 2.13 1.95 1.93 1.93\n",
176898+
" 1.97]\n",
176899+
"Left Matrix Profile: [ inf inf inf 4.42 3.78 2.98 2.74 3.12 2.98 3.8 2.93 2.75 2.45 2.56\n",
176900+
" 2.4 2.35 2.54 2.34 2.77 2.56 2.48 2.58 2.74 2.48 2.29 2.39 2.16 2.51\n",
176901+
" 2.18 2.23 1.57 2.05 1.91 2.07 1.68 1.59 2.19 2.12 1.77 1.78 2.08 2.06\n",
176902+
" 1.99 2.52 2.4 2.07 1.99 2.22 2.1 1.8 2.29 2.16 2.13 1.95 1.93 1.93\n",
176903+
" 1.97]\n",
176904+
"Full Matrix Profile Indices: [52 19 39 45 46 47 48 30 26 49 54 55 56 40 41 42 6 56 53 39 28 42 30 31\n",
176905+
" 38 33 55 38 20 6 7 34 35 54 31 32 54 34 24 19 3 14 21 47 48 3 4 5\n",
176906+
" 44 9 10 36 37 18 33 11 12]\n",
176907+
"Left Matrix Profile Indices: [-1 -1 -1 0 1 2 3 4 2 4 0 1 7 3 9 5 6 12 13 1 9 6 7 10\n",
176908+
" 11 12 13 4 20 6 7 23 24 25 31 32 25 34 24 19 3 14 21 30 3 3 4 5\n",
176909+
" 44 9 10 36 37 18 33 11 12]\n"
176910176910
]
176911176911
}
176912176912
],
@@ -176919,12 +176919,12 @@
176919176919
"\n",
176920176920
"for i in range(len(T_stream), len(T_full)):\n",
176921176921
" t = T_full[i]\n",
176922-
" stream.add(t)\n",
176922+
" stream.update(t)\n",
176923176923
"\n",
176924-
"print(f\"Full Matrix Profile: {np.round(stream.P, 2)}\")\n",
176925-
"print(f\"Left Matrix Profile: {np.round(stream.left_P, 2)}\")\n",
176926-
"print(f\"Full Matrix Profile Indices: {stream.I}\")\n",
176927-
"print(f\"Left Matrix Profile Indices: {stream.left_I}\")"
176924+
"print(f\"Full Matrix Profile: {np.round(stream.P_, 2)}\")\n",
176925+
"print(f\"Left Matrix Profile: {np.round(stream.left_P_, 2)}\")\n",
176926+
"print(f\"Full Matrix Profile Indices: {stream.I_}\")\n",
176927+
"print(f\"Left Matrix Profile Indices: {stream.left_I_}\")"
176928176928
]
176929176929
},
176930176930
{
@@ -176934,18 +176934,6 @@
176934176934
"Of course, it is important to point out that a `-1` value in the left matrix profile indices does <b><u>not</u></b> correspond to the last subsequence in the time series. Instead, it means that the subsequence in that position has no valid nearest neighbor to its left. Consequently, the corresponding left matrix profile value will be set to `np.inf`."
176935176935
]
176936176936
},
176937-
{
176938-
"cell_type": "markdown",
176939-
"metadata": {},
176940-
"source": [
176941-
"## Caveats\n",
176942-
"\n",
176943-
"As with all software, there are a few things to keep in mind when using `stumpy.stumpi`: \n",
176944-
"\n",
176945-
"1. There is currently no support for time series that contain `NaN`/`inf` values (but it's coming soon)\n",
176946-
"2. This only works for self-joins and not AB-joins"
176947-
]
176948-
},
176949176937
{
176950176938
"cell_type": "markdown",
176951176939
"metadata": {},

stumpy/stumpi.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,35 @@ class stumpi(object):
2828
Attributes
2929
----------
3030
P_ : ndarray
31-
The matrix profile for `T`
31+
The updated matrix profile for `T`
3232
3333
I_ : ndarray
34-
The matrix profile indices for `T`
34+
The updated matrix profile indices for `T`
3535
3636
left_P_ : ndarray
37-
The left matrix profile for `T`
37+
The updated left matrix profile for `T`
3838
3939
left_I_ : ndarray
40-
The left matrix profile indices for `T`
40+
The updated left matrix profile indices for `T`
4141
4242
T_ : ndarray
43-
The time series or sequence for which the matrix profile and matrix profile
44-
indices will be computed
43+
The updated time series or sequence for which the matrix profile and matrix
44+
profile indices are computed
4545
4646
Methods
4747
-------
48-
add(t)
49-
Append a single new data point to the time series and update the matrix profile
48+
update(t)
49+
Append a single new data point, `t`, to the time series, `T`, and update the
50+
matrix profile
51+
52+
Notes
53+
-----
54+
`DOI: 10.1007/s10618-017-0519-9 \
55+
<https://www.cs.ucr.edu/~eamonn/MP_journal.pdf>`__
56+
57+
See Table V
58+
59+
Note that line 11 is missing an important `sqrt` operation!
5060
"""
5161

5262
def __init__(self, T, m, excl_zone=None):
@@ -91,7 +101,7 @@ def __init__(self, T, m, excl_zone=None):
91101
Q = self._T[-m:]
92102
self._QT = core.sliding_dot_product(Q, self._T)
93103

94-
def add(self, t):
104+
def update(self, t):
95105
"""
96106
Append a single new data point, `t`, to the existing time series `T` and update
97107
the matrix profile and matrix profile indices.

tests/test_stumpi.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_stumpi_self_join():
2020
stream = stumpi(T, m)
2121
for i in range(34):
2222
t = np.random.rand()
23-
stream.add(t)
23+
stream.update(t)
2424

2525
right_P = stream.P_
2626
right_I = stream.I_
@@ -54,7 +54,7 @@ def test_stumpi_self_join():
5454
stream = stumpi(T, m)
5555
for i in range(34):
5656
t = np.random.rand()
57-
stream.add(t)
57+
stream.update(t)
5858

5959
right_P = stream.P_
6060
right_I = stream.I_
@@ -88,7 +88,7 @@ def test_stumpi_init_nan_inf_self_join(substitute, substitution_locations):
8888
stream = stumpi(T, m)
8989
for i in range(34):
9090
t = np.random.rand()
91-
stream.add(t)
91+
stream.update(t)
9292

9393
right_P = stream.P_
9494
right_I = stream.I_
@@ -114,7 +114,7 @@ def test_stumpi_init_nan_inf_self_join(substitute, substitution_locations):
114114
stream = stumpi(T, m)
115115
for i in range(34):
116116
t = np.random.rand()
117-
stream.add(t)
117+
stream.update(t)
118118

119119
right_P = stream.P_
120120
right_I = stream.I_
@@ -142,7 +142,7 @@ def test_stumpi_stream_nan_inf_self_join(substitute, substitution_locations):
142142
substitution_location = T[30:].shape[0] - 1
143143
T[30:][substitution_location] = substitute
144144
for t in T[30:]:
145-
stream.add(t)
145+
stream.update(t)
146146

147147
right_P = stream.P_
148148
right_I = stream.I_
@@ -166,7 +166,7 @@ def test_stumpi_stream_nan_inf_self_join(substitute, substitution_locations):
166166
substitution_location = T[30:].shape[0] - 1
167167
T[30:][substitution_location] = substitute
168168
for t in T[30:]:
169-
stream.add(t)
169+
stream.update(t)
170170

171171
right_P = stream.P_
172172
right_I = stream.I_
@@ -188,7 +188,7 @@ def test_stumpi_constant_subsequence_self_join():
188188
stream = stumpi(T, m)
189189
for i in range(34):
190190
t = np.random.rand()
191-
stream.add(t)
191+
stream.update(t)
192192

193193
right_P = stream.P_
194194
right_I = stream.I_
@@ -209,7 +209,7 @@ def test_stumpi_constant_subsequence_self_join():
209209
stream = stumpi(T, m)
210210
for i in range(34):
211211
t = np.random.rand()
212-
stream.add(t)
212+
stream.update(t)
213213

214214
right_P = stream.P_
215215
right_I = stream.I_

0 commit comments

Comments
 (0)