确定熊猫系列中是否存在序列,并返回找到该序列的行

时间:2018-12-18 06:09:23

标签: python pandas numpy

我将以下numpy数组存储为Pandas系列。

array([0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0,
   0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,
   0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
   0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,
   1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1,
   0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1,
   1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
   1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0,
   1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
   0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1,
   0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0,
   1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
   0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0,
   1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
   1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1,
   0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1,
   1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1,
   0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0,
   0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
   1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0,
   0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
   1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0,
   1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0,
   1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
   0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
   1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1,
   1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0,
   1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1,
   1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,
   0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0,
   1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
   1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1,
   0, 1, 1, 0, 1, 1, 1])

我想确定数组中是否有一定的'1'序列。如果是这样,我想获取行。即,此数组是否具有三个1的序列?他们在哪里?

我尝试查看Pandas文档,例如 isin(),但是这些对象是在处理特定元素,而不是元素序列。似乎没有任何功能可以满足我的需求。希望有人能提供帮助。谢谢。

2 个答案:

答案 0 :(得分:1)

Python解决方案

您可以使用itertools.groupby来获取所需的内容:

from itertools import groupby

def oneruns_groupby(arr, n):
    ix = 0
    ixs = []
    for k,g in groupby(arr):
        leng = len(list(g))
        if k and leng == n:
            ixs.append(ix)
        ix += leng
    return ixs

print(oneruns_groupby(arr, 3))

因此,如果您要查找所有长度为3(如果有)的所有游程的索引,则可以像这样使用它(我将您的数组称为arr,因为我没有不想复制并粘贴整个大物件):

oneruns_groupby(arr, 3)

输出:

[2, 17, 41, 71, 87, 100, 172, 265, 359, 376, 380, 410, 442, 495, 523, 551, 557, 609, 620, 627, 633, 637, 661, 710, 752]

脾气暴躁的解决方案

这是一个函数,它将为您提供给定长度1的{​​{1}}个值的每次运行的起始索引:

n

对其进行测试:

def oneruns_npcomp(arr, n):
    d = np.diff(np.pad(arr, 1, 'constant'))
    start = (d > 0).nonzero()[0]
    runlen = (d < 0).nonzero()[0] - start

    return start[runlen == n]

输出:

oneruns_npcomp(arr, 3)

快速而肮脏的解决方案

这是Numpy的另一种解决方案:

array([  2,  17,  41,  71,  87, 100, 172, 265, 359, 376, 380, 410, 442,
       495, 523, 551, 557, 609, 620, 627, 633, 637, 661, 710, 752])

尽管要注意,快速而肮脏的方法会找到长度为def oneruns_qd(arr, n): return ((np.diff(np.pad(arr, 1, 'constant'), n) == 0) & (arr[:-n] == 1)).nonzero() 或更长1个值的所有运行。

答案 1 :(得分:0)

这似乎是一个template matching问题。

如果只考虑查找序列,则可以使用np.correlate实现简单的解决方案。

这可以代替绝对差之和,因为任何其他数字序列都将导致相关值<模板长度。

import numpy as np
def find_matching_ones(sequence, length):
  correlated_values = np.correlate(sequence, np.ones((length)), "same")
  return np.where(correlated_values == length)[0] - length//2

def verify_results(sequence, length, indices):
  for idx in indices.tolist():
    reference = sequence[idx:(idx + length)]
    if not np.all(reference == 1):
      print(idx, reference)
      return False
  return True

for n in range(3, 7):
  indices = find_matching_ones(sequence, n)
  if verify_results(sequence, n, indices):
    print("Results matched for length ", n)
  else:
    print("Results did not match for length ", n)

此代码假定您的数组名为sequence