Numpy: Test of an array items are above some value, x consecutive number of times?
up vote
2
down vote
favorite
I am trying to test to see if the values in an array are above some value a consecutive number of times.
For example
arr1 = np.array([1,2,1,3,4,5,6,7])
arr2 = np.array([1,2,1,3,4,2,6,7])
Say I want to test to see if an item in the array is >=3 for four consecutive periods. The test would return true for arr1 but false for arr2.
python numpy
add a comment |
up vote
2
down vote
favorite
I am trying to test to see if the values in an array are above some value a consecutive number of times.
For example
arr1 = np.array([1,2,1,3,4,5,6,7])
arr2 = np.array([1,2,1,3,4,2,6,7])
Say I want to test to see if an item in the array is >=3 for four consecutive periods. The test would return true for arr1 but false for arr2.
python numpy
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am trying to test to see if the values in an array are above some value a consecutive number of times.
For example
arr1 = np.array([1,2,1,3,4,5,6,7])
arr2 = np.array([1,2,1,3,4,2,6,7])
Say I want to test to see if an item in the array is >=3 for four consecutive periods. The test would return true for arr1 but false for arr2.
python numpy
I am trying to test to see if the values in an array are above some value a consecutive number of times.
For example
arr1 = np.array([1,2,1,3,4,5,6,7])
arr2 = np.array([1,2,1,3,4,2,6,7])
Say I want to test to see if an item in the array is >=3 for four consecutive periods. The test would return true for arr1 but false for arr2.
python numpy
python numpy
asked Nov 9 at 15:32
spitfiredd
82511125
82511125
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
5
down vote
accepted
Here's one way with convolution -
def cross_thresh_convolve(arr, thresh, N):
# Detect if arr crosses thresh for N consecutive times anywhere
return (np.convolve(arr>=thresh,np.ones(N,dtype=int))==N).any()
Alternatively with binary-dilation -
from scipy.ndimage.morphology import binary_erosion
def cross_thresh_erosion(arr, thresh, N):
return binary_erosion(arr>=thresh, np.ones(N)).any()
Sample runs -
In [43]: arr1 = np.array([1,2,1,3,4,5,6,7])
...: arr2 = np.array([1,2,1,3,4,2,6,7])
In [44]: print cross_thresh_convolve(arr1, thresh=3, N=4)
...: print cross_thresh_erosion(arr1, thresh=3, N=4)
...: print cross_thresh_convolve(arr2, thresh=3, N=4)
...: print cross_thresh_erosion(arr2, thresh=3, N=4)
True
True
False
False
Generic comparisons
To cover generic comparisons, say if we want to look for greater or less-than or even simply compare for equality against a value, we could use NumPy builtin comparison functions to replace the arr>=thresh part from earlier solutions and hence give ourselves generic implementations, like so -
def consecutive_comp_convolve(arr, comp, N, comparison=np.greater_equal):
return (np.convolve(comparison(arr,comp),np.ones(N,dtype=int))==N).any()
def consecutive_comp_erosion(arr, comp, N, comparison=np.greater_equal):
return binary_erosion(comparison(arr,comp), np.ones(N)).any()
Hence, our specific case runs would be -
consecutive_comp_convolve(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_convolve(arr2, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr2, comp=3, N=4, comparison=np.greater_equal)
add a comment |
up vote
1
down vote
Here is a lowtech but fast method. Construct the boolean array, form the cumsum() and compare each element to the one n places away. If the difference is n this must be a streak of Trues.
def check_streak(a, th, n):
ps = (a>=th).cumsum()
return (ps[n:]-ps[:ps.size-n] == n).any()
add a comment |
up vote
0
down vote
Another solution (but slower than the others)
import numpy as np
from numpy.lib.stride_tricks import as_strided
def f(arr, threshold=3, n=4):
arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
return (arr >= threshold).all(axis=1).any()
# How it works:
# arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# n = 4
# threshold = 3
# arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
# print(arr)
# [[1 2 3 4]
# [2 3 4 5]
# [3 4 5 6]
# [4 5 6 7]
# [5 6 7 8]]
# print(arr >= threshold)
# [[False False True True]
# [False True True True]
# [ True True True True]
# [ True True True True]
# [ True True True True]]
# print((arr >= threshold).all(axis=1))
# [False False True True True]
# print((arr >= threshold).all(axis=1).any())
# True
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228719%2fnumpy-test-of-an-array-items-are-above-some-value-x-consecutive-number-of-time%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
Here's one way with convolution -
def cross_thresh_convolve(arr, thresh, N):
# Detect if arr crosses thresh for N consecutive times anywhere
return (np.convolve(arr>=thresh,np.ones(N,dtype=int))==N).any()
Alternatively with binary-dilation -
from scipy.ndimage.morphology import binary_erosion
def cross_thresh_erosion(arr, thresh, N):
return binary_erosion(arr>=thresh, np.ones(N)).any()
Sample runs -
In [43]: arr1 = np.array([1,2,1,3,4,5,6,7])
...: arr2 = np.array([1,2,1,3,4,2,6,7])
In [44]: print cross_thresh_convolve(arr1, thresh=3, N=4)
...: print cross_thresh_erosion(arr1, thresh=3, N=4)
...: print cross_thresh_convolve(arr2, thresh=3, N=4)
...: print cross_thresh_erosion(arr2, thresh=3, N=4)
True
True
False
False
Generic comparisons
To cover generic comparisons, say if we want to look for greater or less-than or even simply compare for equality against a value, we could use NumPy builtin comparison functions to replace the arr>=thresh part from earlier solutions and hence give ourselves generic implementations, like so -
def consecutive_comp_convolve(arr, comp, N, comparison=np.greater_equal):
return (np.convolve(comparison(arr,comp),np.ones(N,dtype=int))==N).any()
def consecutive_comp_erosion(arr, comp, N, comparison=np.greater_equal):
return binary_erosion(comparison(arr,comp), np.ones(N)).any()
Hence, our specific case runs would be -
consecutive_comp_convolve(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_convolve(arr2, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr2, comp=3, N=4, comparison=np.greater_equal)
add a comment |
up vote
5
down vote
accepted
Here's one way with convolution -
def cross_thresh_convolve(arr, thresh, N):
# Detect if arr crosses thresh for N consecutive times anywhere
return (np.convolve(arr>=thresh,np.ones(N,dtype=int))==N).any()
Alternatively with binary-dilation -
from scipy.ndimage.morphology import binary_erosion
def cross_thresh_erosion(arr, thresh, N):
return binary_erosion(arr>=thresh, np.ones(N)).any()
Sample runs -
In [43]: arr1 = np.array([1,2,1,3,4,5,6,7])
...: arr2 = np.array([1,2,1,3,4,2,6,7])
In [44]: print cross_thresh_convolve(arr1, thresh=3, N=4)
...: print cross_thresh_erosion(arr1, thresh=3, N=4)
...: print cross_thresh_convolve(arr2, thresh=3, N=4)
...: print cross_thresh_erosion(arr2, thresh=3, N=4)
True
True
False
False
Generic comparisons
To cover generic comparisons, say if we want to look for greater or less-than or even simply compare for equality against a value, we could use NumPy builtin comparison functions to replace the arr>=thresh part from earlier solutions and hence give ourselves generic implementations, like so -
def consecutive_comp_convolve(arr, comp, N, comparison=np.greater_equal):
return (np.convolve(comparison(arr,comp),np.ones(N,dtype=int))==N).any()
def consecutive_comp_erosion(arr, comp, N, comparison=np.greater_equal):
return binary_erosion(comparison(arr,comp), np.ones(N)).any()
Hence, our specific case runs would be -
consecutive_comp_convolve(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_convolve(arr2, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr2, comp=3, N=4, comparison=np.greater_equal)
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
Here's one way with convolution -
def cross_thresh_convolve(arr, thresh, N):
# Detect if arr crosses thresh for N consecutive times anywhere
return (np.convolve(arr>=thresh,np.ones(N,dtype=int))==N).any()
Alternatively with binary-dilation -
from scipy.ndimage.morphology import binary_erosion
def cross_thresh_erosion(arr, thresh, N):
return binary_erosion(arr>=thresh, np.ones(N)).any()
Sample runs -
In [43]: arr1 = np.array([1,2,1,3,4,5,6,7])
...: arr2 = np.array([1,2,1,3,4,2,6,7])
In [44]: print cross_thresh_convolve(arr1, thresh=3, N=4)
...: print cross_thresh_erosion(arr1, thresh=3, N=4)
...: print cross_thresh_convolve(arr2, thresh=3, N=4)
...: print cross_thresh_erosion(arr2, thresh=3, N=4)
True
True
False
False
Generic comparisons
To cover generic comparisons, say if we want to look for greater or less-than or even simply compare for equality against a value, we could use NumPy builtin comparison functions to replace the arr>=thresh part from earlier solutions and hence give ourselves generic implementations, like so -
def consecutive_comp_convolve(arr, comp, N, comparison=np.greater_equal):
return (np.convolve(comparison(arr,comp),np.ones(N,dtype=int))==N).any()
def consecutive_comp_erosion(arr, comp, N, comparison=np.greater_equal):
return binary_erosion(comparison(arr,comp), np.ones(N)).any()
Hence, our specific case runs would be -
consecutive_comp_convolve(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_convolve(arr2, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr2, comp=3, N=4, comparison=np.greater_equal)
Here's one way with convolution -
def cross_thresh_convolve(arr, thresh, N):
# Detect if arr crosses thresh for N consecutive times anywhere
return (np.convolve(arr>=thresh,np.ones(N,dtype=int))==N).any()
Alternatively with binary-dilation -
from scipy.ndimage.morphology import binary_erosion
def cross_thresh_erosion(arr, thresh, N):
return binary_erosion(arr>=thresh, np.ones(N)).any()
Sample runs -
In [43]: arr1 = np.array([1,2,1,3,4,5,6,7])
...: arr2 = np.array([1,2,1,3,4,2,6,7])
In [44]: print cross_thresh_convolve(arr1, thresh=3, N=4)
...: print cross_thresh_erosion(arr1, thresh=3, N=4)
...: print cross_thresh_convolve(arr2, thresh=3, N=4)
...: print cross_thresh_erosion(arr2, thresh=3, N=4)
True
True
False
False
Generic comparisons
To cover generic comparisons, say if we want to look for greater or less-than or even simply compare for equality against a value, we could use NumPy builtin comparison functions to replace the arr>=thresh part from earlier solutions and hence give ourselves generic implementations, like so -
def consecutive_comp_convolve(arr, comp, N, comparison=np.greater_equal):
return (np.convolve(comparison(arr,comp),np.ones(N,dtype=int))==N).any()
def consecutive_comp_erosion(arr, comp, N, comparison=np.greater_equal):
return binary_erosion(comparison(arr,comp), np.ones(N)).any()
Hence, our specific case runs would be -
consecutive_comp_convolve(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr1, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_convolve(arr2, comp=3, N=4, comparison=np.greater_equal)
consecutive_comp_erosion(arr2, comp=3, N=4, comparison=np.greater_equal)
edited Nov 9 at 16:13
answered Nov 9 at 15:36
Divakar
153k1479169
153k1479169
add a comment |
add a comment |
up vote
1
down vote
Here is a lowtech but fast method. Construct the boolean array, form the cumsum() and compare each element to the one n places away. If the difference is n this must be a streak of Trues.
def check_streak(a, th, n):
ps = (a>=th).cumsum()
return (ps[n:]-ps[:ps.size-n] == n).any()
add a comment |
up vote
1
down vote
Here is a lowtech but fast method. Construct the boolean array, form the cumsum() and compare each element to the one n places away. If the difference is n this must be a streak of Trues.
def check_streak(a, th, n):
ps = (a>=th).cumsum()
return (ps[n:]-ps[:ps.size-n] == n).any()
add a comment |
up vote
1
down vote
up vote
1
down vote
Here is a lowtech but fast method. Construct the boolean array, form the cumsum() and compare each element to the one n places away. If the difference is n this must be a streak of Trues.
def check_streak(a, th, n):
ps = (a>=th).cumsum()
return (ps[n:]-ps[:ps.size-n] == n).any()
Here is a lowtech but fast method. Construct the boolean array, form the cumsum() and compare each element to the one n places away. If the difference is n this must be a streak of Trues.
def check_streak(a, th, n):
ps = (a>=th).cumsum()
return (ps[n:]-ps[:ps.size-n] == n).any()
answered Nov 9 at 15:53
Paul Panzer
29.4k21240
29.4k21240
add a comment |
add a comment |
up vote
0
down vote
Another solution (but slower than the others)
import numpy as np
from numpy.lib.stride_tricks import as_strided
def f(arr, threshold=3, n=4):
arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
return (arr >= threshold).all(axis=1).any()
# How it works:
# arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# n = 4
# threshold = 3
# arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
# print(arr)
# [[1 2 3 4]
# [2 3 4 5]
# [3 4 5 6]
# [4 5 6 7]
# [5 6 7 8]]
# print(arr >= threshold)
# [[False False True True]
# [False True True True]
# [ True True True True]
# [ True True True True]
# [ True True True True]]
# print((arr >= threshold).all(axis=1))
# [False False True True True]
# print((arr >= threshold).all(axis=1).any())
# True
add a comment |
up vote
0
down vote
Another solution (but slower than the others)
import numpy as np
from numpy.lib.stride_tricks import as_strided
def f(arr, threshold=3, n=4):
arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
return (arr >= threshold).all(axis=1).any()
# How it works:
# arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# n = 4
# threshold = 3
# arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
# print(arr)
# [[1 2 3 4]
# [2 3 4 5]
# [3 4 5 6]
# [4 5 6 7]
# [5 6 7 8]]
# print(arr >= threshold)
# [[False False True True]
# [False True True True]
# [ True True True True]
# [ True True True True]
# [ True True True True]]
# print((arr >= threshold).all(axis=1))
# [False False True True True]
# print((arr >= threshold).all(axis=1).any())
# True
add a comment |
up vote
0
down vote
up vote
0
down vote
Another solution (but slower than the others)
import numpy as np
from numpy.lib.stride_tricks import as_strided
def f(arr, threshold=3, n=4):
arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
return (arr >= threshold).all(axis=1).any()
# How it works:
# arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# n = 4
# threshold = 3
# arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
# print(arr)
# [[1 2 3 4]
# [2 3 4 5]
# [3 4 5 6]
# [4 5 6 7]
# [5 6 7 8]]
# print(arr >= threshold)
# [[False False True True]
# [False True True True]
# [ True True True True]
# [ True True True True]
# [ True True True True]]
# print((arr >= threshold).all(axis=1))
# [False False True True True]
# print((arr >= threshold).all(axis=1).any())
# True
Another solution (but slower than the others)
import numpy as np
from numpy.lib.stride_tricks import as_strided
def f(arr, threshold=3, n=4):
arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
return (arr >= threshold).all(axis=1).any()
# How it works:
# arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# n = 4
# threshold = 3
# arr = as_strided(arr, shape=(arr.shape[0]-n+1, n), strides=2*arr.strides)
# print(arr)
# [[1 2 3 4]
# [2 3 4 5]
# [3 4 5 6]
# [4 5 6 7]
# [5 6 7 8]]
# print(arr >= threshold)
# [[False False True True]
# [False True True True]
# [ True True True True]
# [ True True True True]
# [ True True True True]]
# print((arr >= threshold).all(axis=1))
# [False False True True True]
# print((arr >= threshold).all(axis=1).any())
# True
edited Nov 9 at 16:53
answered Nov 9 at 16:19
AndyK
828718
828718
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228719%2fnumpy-test-of-an-array-items-are-above-some-value-x-consecutive-number-of-time%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown