找到一维数组/列表的元素之间差异的函数,例如x [n] -x [n-1],x [n-2] -x [n-1]其中n是数组/列表的大小

时间:2017-01-27 18:52:44

标签: python arrays numpy

我有一个包含整数的一维数组或列表,例如x = [0, 2, 4, 7, 8, 12, 15, 23, 28, 39]

我想要一个执行以下操作的函数: 返回存储

的列表/数组
x[9]-x[8],  x[8]-x[7],  x[7]-x[6], ......., x[1]-x[0]

在这个例子中,我应该得到一个列表/数组给出[11,5,8,3,4,1,3,2,2]。

我需要这个函数在while循环中运行,其中每个循环的列表/数组x的大小增加1。

我如何在Python或Numpy中执行此操作?

this other question不同,这个问题寻求从列表/数组末尾到它开始的元素之间的区别:这个问题在数学上与另一个问题不同。

5 个答案:

答案 0 :(得分:3)

使用带有普通列表的切片表示法

>>> x = [0, 2, 4, 7, 8, 12, 15, 23, 28, 39]
>>> [ a-b for a,b in zip(x[::-1],x[-2::-1]) ]
[11, 5, 8, 3, 4, 1, 3, 2, 2]
>>> 

为了避免不必要的副本,可以使用产生对的函数来帮助这个

>>> def pairwise(iterable):
        it = iter(iterable)
        a = next(it)
        for b in it:
            yield a,b
            a = b


>>> [ a-b for a,b in pairwise(reversed(x))]
[11, 5, 8, 3, 4, 1, 3, 2, 2]
>>> 

答案 1 :(得分:3)

In [1084]: x = [0, 2, 4, 7, 8, 12, 15, 23, 28, 39]

numpy.diff可以轻松实现这种差异

In [1085]: np.diff(x)
Out[1085]: array([ 2,  2,  3,  1,  4,  3,  8,  5, 11])

顺序错误,但可以使用[::-1](适用于列表和数组)轻松更改:

In [1086]: np.diff(x)[::-1]
Out[1086]: array([11,  5,  8,  3,  4,  1,  3,  2,  2])
In [1087]: np.diff(x[::-1])
Out[1087]: array([-11,  -5,  -8,  -3,  -4,  -1,  -3,  -2,  -2])

您提到在添加到列表时执行此计算。让我们尝试一下,从x

迭代地构建一个新列表
In [1088]: y=[]; dy=[]
In [1089]: for i in x:
      ...:     if y: # not empty
      ...:         dy.insert(0, i-y[-1])
      ...:     y.append(i)

In [1090]: y
Out[1090]: [0, 2, 4, 7, 8, 12, 15, 23, 28, 39]
In [1091]: dy
Out[1091]: [11, 5, 8, 3, 4, 1, 3, 2, 2]

列表追加比数组连接更快(np.append只是一个封面)。因此,如果您已经在进行循环,那么坚持使用列表是有意义的。

与列表区别开来的几种方法之一:

In [1093]: [i-j for i,j in zip(x[1:],x[:-1])]
Out[1093]: [2, 2, 3, 1, 4, 3, 8, 5, 11]

之后添加列表反转更简单,而不是弄清楚如何重写zip条款。

np.diff(a)只是:

In [1094]: xa=np.array(x)
In [1095]: xa[1:]-xa[:-1]
Out[1095]: array([ 2,  2,  3,  1,  4,  3,  8,  5, 11])

答案 2 :(得分:2)

您必须将diff函数应用于反转列表,然后更改符号。

import numpy as np 

x = [0, 2, 4, 7, 8, 12, 15, 23, 28, 39]
y = np.asarray(x)
z = -np.diff(y[::-1])
print(z)

输出:

[11  5  8  3  4  1  3  2  2]

答案 3 :(得分:1)

使用numpy,你可以这样做:

def f(x):
    x = np.array(x)
    y = np.copy(x)
    return y[:-1] - x[1:]

在此函数中,将列表x转换为numpy数组,然后将该数组复制到y。 y[:-1]是除最后一个元素之外的整个数组,x[1:]是除第一个元素之外的整个数组。减去这两个数组将为您提供所需的结果。

你需要在这里使用numpy的原因是因为numpy数组可以在列表之间进行逐项减法,而对于普通的python列表,这种减法并不起作用。

答案 4 :(得分:0)

您需要在反转列表上方滑动窗口,然后获取该差异。 Here是获取滑动窗口的一种方法,复制如下。

from itertools import islice

def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result    
    for elem in it:
        result = result[1:] + (elem,)
        yield result

def sliding_differences(l):
    for a, b in window(reversed(l)):
        yield a-b

x = [0, 2, 4, 7, 8, 12, 15, 23, 28, 39]
print(list(sliding_differences(x)))

输出:

[11, 5, 8, 3, 4, 1, 3, 2, 2]