Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在列表中查找数量不断增加的组(具有不同的增量)_Python_Pandas_Numpy - Fatal编程技术网

Python 在列表中查找数量不断增加的组(具有不同的增量)

Python 在列表中查找数量不断增加的组(具有不同的增量),python,pandas,numpy,Python,Pandas,Numpy,我有一个列表,其中包含具有不同增量的递增数字的“组”。下面是一个例子: l = [0, 1, 5, 8, 10, 20, 30, 40, 45, 48, 77, 100, 200, 300, 400] 我想回去: [[0], [1], [5], [8], [10, 20, 30, 40], [45], [48], [77], [100, 200, 300, 400]] 说明:0、1、5、8不遵循固定的增量(+1、+4、+3),而[10、20、30、40]都具有固定的+10增量 我知道如何使

我有一个列表,其中包含具有不同增量的递增数字的“组”。下面是一个例子:

l = [0, 1, 5, 8, 10, 20, 30, 40, 45, 48, 77, 100, 200, 300, 400]
我想回去:

[[0], [1], [5], [8], [10, 20, 30, 40], [45], [48], [77], [100, 200, 300, 400]]
说明:0、1、5、8不遵循固定的增量(+1、+4、+3),而[10、20、30、40]都具有固定的+10增量


我知道如何使用for循环和
curr_group
curr_delta
等变量来实现这一点,但我希望避免这种情况

使用熊猫,我可以得到:

import pandas as pd

df = pd.DataFrame({'col': [0, 1, 5, 8, 10, 20, 30, 40, 45, 48, 77, 100, 200, 300, 400]})
df['shift_diff'] = (df.diff() != df.diff().shift(-1)).astype('int')
df['group'] = df.shift_diff.cumsum()
print list(df.groupby('group').col.apply(list))
哪个输出

[[0], [1], [5], [8], [10, 20, 30], [40], [45], [48], [77], [100, 200, 300], [400]]
非常接近,但是所有长度大于1的组(
[10,20,30]
[100200300]
)都缺少最后一个元素


一个简短而优雅的解决方案将不胜感激!谢谢你这是你想要的吗

df['group'] = (~((df-df.shift()).diff().eq(0)|(df-df.shift(-1)).diff().eq(0))).cumsum()
print(list(df.groupby('group').col.apply(list)))
[[0], [1], [5], [8], [10, 20, 30, 40], [45], [48], [77], [100, 200, 300, 400]]

你不一定需要熊猫,尽管它可能更快。我不知道

我将解释作为注释放在代码中:

array = [1, 4, 5, 10, 20, 30, 40, 15, 17, 19, 2, 5, 3, 100, 200, 300, 400]

def f(array):
    if len(array) == 1: return [array] # Special case for singleton array
    if len(array) == 2: return [[array[0]], [array[1]]] # Special case for pair
    results = []
    index = 2
    while index < len(array): # This will look back by 2, so if the array is too small, apply special cases
        delta = array[index] - array[index - 1] # Difference between current and last element
        if delta == array[index - 1] - array[index - 2]: # If the three elements are all equal
            results.append(array[index - 2:index + 1]) # Append the group of the current three elements
            index += 1 # Go forward one
            while index < len(array) and delta == array[index] - array[index - 1]: # Keep adding until the list is exhausted or the next element is no longer part of this group
                results[-1].append(array[index]) # Add the current element
                index += 1
        else: # If the three elements don't have the same deltas
            results.append([array[index - 2]]) # Append the element and keep going
        index += 1
    return results

print(f(array))
array=[1,4,5,10,20,30,40,15,17,19,2,5,31000,200,300,400]
def f(阵列):
如果len(array)==1:返回[array]#单例数组的特例
如果len(array)==2:返回[[array[0]],[array[1]]]#pair的特殊情况
结果=[]
指数=2
而index

您可以在线试用,这也使阅读注释变得更容易,因为它足够宽,可以容纳注释。这里是一个python版本,它使用惰性函数查找列表中类似差异的长度。输入列表返回一个生成器,该生成器将返回共享差异的元素数,除非该差异是单数,在这种情况下,它将返回1

您可以使用它将列表切成块来创建新列表

from itertools import groupby

def diff_group_len(x):
    dx = (x2-x1 for x1,x2 in zip(x,x[1:]))
    dg = (len(tuple(g)) for _,g in groupby(dx))
    SKIP = False
    for group_size in dg:
        if SKIP:
            SKIP = False
            continue
        if group_size>1:
            SKIP = True
            yield group_size+1
        else:
            yield group_size
定义后,我们可以使用它在列表中查找束的长度。长度用于对列表进行切片

out = []
start = 0
for s in diff_group_len(l):
    out.append(l[start:start+s])
    start += s

out
# returns:
[[0],
 [1],
 [5],
 [8],
 [10, 20, 30, 40],
 [45, 48, 51],
 [77],
 [100, 200, 300, 400]]

那是。。。美丽的。非常感谢!我有一种感觉,在那里的某个地方有一个布尔逻辑的把戏。荣誉请问你是怎么想出这个解决办法的?这是一种常见的差异/移位技巧吗?谢谢@GregSadetsky它是diff of diff,所以我们失去了每组两个单元格的信息,
shift
我们失去了底部的两个,
shift
向上我们失去了顶部的两个,然后我们使用逻辑
我们得到了所有:-)我想我得到了-
(df df.shift()).diff()
计算增量增量的增量,而第二个
(df.shift(-1)).diff()。只要增量的增量为0,数字就会有规律地增加(这
.eq(0)
检查)。逻辑not和cumsum()完成了这幅图。太棒了!:-)再次感谢谢谢你,这太完美了!干杯