代码之家  ›  专栏  ›  技术社区  ›  CurtLH

使用可自定义的数字间距查找数字跑步记录

  •  5
  • CurtLH  · 技术社区  · 7 年前

    我有一个排序的整数列表,我发现想要找到这个列表中运行的数字。我已经看到许多例子,当寻找数字运行的增量为1,但我也希望寻找数字运行的差异是可定制的。

    例如,假设我有以下数字列表:

    nums = [1, 2, 3, 6, 7, 8, 10, 12, 14, 18, 25, 28, 31, 39]
    

    使用找到的示例 here ,我可以找到以下号码:

    [[1, 2, 3], [6, 7, 8], [10], [12], [14], [18], [25], [28], [31], [39]]
    

    但是,我想寻找两个数字之间的差异可能超过1的数字运行。例如,我想要距离小于或等于2的所有数字跑步。

    [[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]] 
    

    或者我想要所有距离小于或等于3的数字跑步。

    [[1, 2, 3, 6, 7, 8, 10, 12, 14], [18], [25, 28, 31], [39]]
    

    这是我现在正在使用的函数,以获得距离为1的数字跑步。

    def runs(seq, n):
        result = []
        for s in seq:
            if not result or s != result[-1][-1] + n:
                # Start a new run if we can't continue the previous one.
                result.append([])
            result[-1].append(s)
        return result
    

    如果我设置了当前函数 n=1 ,然后我找到所有连续的数字序列。如果我设置 n=2 ,那么我只发现 [8, 10, 12, 14] . 如何修改此函数以查找小于或等于的数字运行 n ?

    我想做到这一点:

    runs(num, 2)
    [[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]] 
    
    3 回复  |  直到 7 年前
        1
  •  7
  •   cs95 abhishek58g    7 年前

    迭代的 分组方式 for

    我只是用这个修改你的代码。为了简化事情,你可以初始化 result 具有 seq[0]

    def runs(seq, n):
        result = [[seq[0]]]
        for s in seq[1:]:
            if s - result[-1][-1] > n:  # Keep it simple. Compare the delta.
                result.append([])
            result[-1].append(s)
    
        return result
    

    >>> runs(nums, 1)
    [[1, 2, 3], [6, 7, 8], [10], [12], [14], [18], [25], [28], [31], [39]]
    >>> runs(nums, 2)
    [[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]]
    

    pandas.GroupBy

    如果你想得到幻想,你可以使用 groupby 成语,熊猫容易学。

    import pandas as pd
    
    def runs2(seq, n):
        s = pd.Series(seq)
        return s.groupby(s.diff().gt(n).cumsum()).apply(pd.Series.tolist).tolist()
    

    >>> runs2(nums, 3)
    [[1, 2, 3, 6, 7, 8, 10, 12, 14], [18], [25, 28, 31], [39]]
    

    这里有两个基本要素:grouper(您正在对其进行分组的谓词)和agg函数(您将对每个组应用的函数)

    石斑鱼是 s.diff().gt(n).cumsum() ,细分计算三件事:

    1. 元素之间的差异 seq 使用 diff
    2. 一个布尔掩码,指示diff是否大于 n
    3. 进行累计和(或计数)以确定组

    此操作的输出为

    s.diff().gt(n).cumsum()
    
    0     0
    1     0
    2     0
    3     1
    4     1
    5     1
    6     1
    7     1
    8     1
    9     2
    10    3
    11    4
    12    5
    13    6
    dtype: int64
    

    agg函数是 pd.Series.tolist ,并将任何序列转换为列表。这就是我们需要的,一个嵌套列表。

        2
  •  2
  •   AGN Gazer    7 年前
    def runs(nums, n):
        idx = np.flatnonzero(np.ediff1d(nums, n + 1, n + 1) > n)
        return [nums[i1:i2] for i1, i2 in zip(idx[:-1], idx[1:])]
    

    然后,

    >>> runs(nums, 3)
    [[1, 2, 3, 6, 7, 8, 10, 12, 14], [18], [25, 28, 31], [39]]
    
        3
  •  1
  •   Waket Zheng    7 年前
    In [4]: def runs(seq, n):
       ...:     indexs = [i for i in range(len(seq)) if i==0 or seq[i]-seq[i-1]>n]
       ...:     return [seq[a:b] for a, b in zip(indexs, indexs[1:]+[len(seq)])]
       ...: 
       ...: 
    
    In [5]: runs(nums, 3)
    Out[5]: [[1, 2, 3, 6, 7, 8, 10, 12, 14], [18], [25, 28, 31], [39]]
    
    In [6]: runs(nums, 2)
    Out[6]: [[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]]
    
    推荐文章