我有一个包含整数的一维数组或列表,例如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不同,这个问题寻求从列表/数组末尾到它开始的元素之间的区别:这个问题在数学上与另一个问题不同。
答案 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]