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.










share|improve this question


























    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.










    share|improve this question
























      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.










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 9 at 15:32









      spitfiredd

      82511125




      82511125
























          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)





          share|improve this answer






























            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()





            share|improve this answer




























              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





              share|improve this answer























                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
                });


                }
                });














                draft saved

                draft discarded


















                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)





                share|improve this answer



























                  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)





                  share|improve this answer

























                    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)





                    share|improve this answer














                    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)






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 9 at 16:13

























                    answered Nov 9 at 15:36









                    Divakar

                    153k1479169




                    153k1479169
























                        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()





                        share|improve this answer

























                          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()





                          share|improve this answer























                            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()





                            share|improve this answer












                            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()






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 9 at 15:53









                            Paul Panzer

                            29.4k21240




                            29.4k21240






















                                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





                                share|improve this answer



























                                  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





                                  share|improve this answer

























                                    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





                                    share|improve this answer














                                    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






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Nov 9 at 16:53

























                                    answered Nov 9 at 16:19









                                    AndyK

                                    828718




                                    828718






























                                        draft saved

                                        draft discarded




















































                                        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.




                                        draft saved


                                        draft discarded














                                        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





















































                                        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







                                        這個網誌中的熱門文章

                                        Academy of Television Arts & Sciences

                                        L'Équipe

                                        1995 France bombings