Python中增加整数序列的快速增量编码

Python中增加整数序列的快速增量编码,python,algorithm,compression,Python,Algorithm,Compression,给定a=[1,2,3,4,5] 编码后,a'=[1,1,1,1,1],每个元素表示与其前一个元素相比的差异 我知道这是可以做到的 for i in range(len(a) - 1, 0, -1): a[i] = a[i] - a[i - 1] 有没有更快的办法?我正在处理20亿个数字,这个过程大约需要30分钟。您可以使用,例如: 将numpy导入为np a=[1,2,3,4,5] npa=np.数组(a) a_diff=np.diff(npa) 您可以使用,例如: 将numpy导入为

给定
a=[1,2,3,4,5]

编码后,
a'=[1,1,1,1,1]
,每个元素表示与其前一个元素相比的差异

我知道这是可以做到的

for i in range(len(a) - 1, 0, -1):
    a[i] = a[i] - a[i - 1]
有没有更快的办法?我正在处理20亿个数字,这个过程大约需要30分钟。

您可以使用,例如:

将numpy导入为np
a=[1,2,3,4,5]
npa=np.数组(a)
a_diff=np.diff(npa)
您可以使用,例如:

将numpy导入为np
a=[1,2,3,4,5]
npa=np.数组(a)
a_diff=np.diff(npa)

您可以使用
zip
将列表与偏移版本放在一起,然后减去这些值

a = [1, 2, 3, 4, 5]

a[1:] = [nxt - cur for cur, nxt in zip(a, a[1:])]
print(a)
输出:

[1, 1, 1, 1, 1]
[1, 1, 1, ..., 1]
出于兴趣,我通过
timeit
运行了这个原始代码和@ynotzort答案,这比短列表的
numpy
代码快得多;保持较快速度,最高可达10米左右的数值;两者都比原始代码快30%左右。当列表大小增加到10米以上时,
numpy
代码的速度会更快,最终从大约20米的值开始会更快

更新

还测试了
starmap
代码,在20M的值下比
numpy
代码快约40%

更新2

@Chris的回答中有一些更全面的性能数据。通过使用
itertools.islice
生成偏移量列表,可以进一步加快回答速度(约10%):

a = [a[0], *[nxt - cur for cur, nxt in zip(a, islice(a, 1, None))]]

您可以使用
zip
将列表与偏移版本放在一起,然后减去这些值

a = [1, 2, 3, 4, 5]

a[1:] = [nxt - cur for cur, nxt in zip(a, a[1:])]
print(a)
输出:

[1, 1, 1, 1, 1]
[1, 1, 1, ..., 1]
出于兴趣,我通过
timeit
运行了这个原始代码和@ynotzort答案,这比短列表的
numpy
代码快得多;保持较快速度,最高可达10米左右的数值;两者都比原始代码快30%左右。当列表大小增加到10米以上时,
numpy
代码的速度会更快,最终从大约20米的值开始会更快

更新

还测试了
starmap
代码,在20M的值下比
numpy
代码快约40%

更新2

@Chris的回答中有一些更全面的性能数据。通过使用
itertools.islice
生成偏移量列表,可以进一步加快回答速度(约10%):

a = [a[0], *[nxt - cur for cur, nxt in zip(a, islice(a, 1, None))]]

单向使用
itertools.starmap
islice
operator.sub

from operator import sub
from itertools import starmap, islice

l = list(range(1, 10000000))

[l[0], *starmap(sub, zip(islice(l, 1, None), l))]
输出:

[1, 1, 1, 1, 1]
[1, 1, 1, ..., 1]

基准:

l = list(range(1, 100000000))

# OP's method
%timeit [l[i] - l[i - 1] for i in range(len(l) - 1, 0, -1)]    
# 14.2 s ± 373 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# numpy approach by @ynotzort
%timeit np.diff(l)
# 8.52 s ± 301 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# zip approach by @Nick
%timeit [nxt - cur for cur, nxt in zip(l, l[1:])]
# 7.96 s ± 243 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# itertool and operator approach by @Chris
%timeit [l[0], *starmap(sub, zip(islice(l, 1, None), l))]
# 6.4 s ± 255 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

单向使用
itertools.starmap
islice
operator.sub

from operator import sub
from itertools import starmap, islice

l = list(range(1, 10000000))

[l[0], *starmap(sub, zip(islice(l, 1, None), l))]
输出:

[1, 1, 1, 1, 1]
[1, 1, 1, ..., 1]

基准:

l = list(range(1, 100000000))

# OP's method
%timeit [l[i] - l[i - 1] for i in range(len(l) - 1, 0, -1)]    
# 14.2 s ± 373 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# numpy approach by @ynotzort
%timeit np.diff(l)
# 8.52 s ± 301 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# zip approach by @Nick
%timeit [nxt - cur for cur, nxt in zip(l, l[1:])]
# 7.96 s ± 243 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# itertool and operator approach by @Chris
%timeit [l[0], *starmap(sub, zip(islice(l, 1, None), l))]
# 6.4 s ± 255 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在2000万的值下,这比
numpy
zip
代码快约40%。。。(请参阅我关于基准测试的说明)有趣的是,您的结果显示我的代码优于@ynotzort。我想知道它是否与每台机器上的内存量有关。@Nick你是否将列表作为numpy数组的一部分(
np.array(l)
)?我将其包括在设置中,因此它只会运行一次。@Nick对于
numpy
部分,将列表转换为
numpy.ndarray
比执行diff需要更长的时间,我认为将这种转换包括在timeit中是一个公平的比较。也许这就是造成差异的原因。在2000万的值下,这比
numpy
zip
代码快40%左右。。。(请参阅我关于基准测试的说明)有趣的是,您的结果显示我的代码优于@ynotzort。我想知道它是否与每台机器上的内存量有关。@Nick你是否将列表作为numpy数组的一部分(
np.array(l)
)?我将其包括在设置中,因此它只会运行一次。@Nick对于
numpy
部分,将列表转换为
numpy.ndarray
比执行diff需要更长的时间,我认为将这种转换包括在timeit中是一个公平的比较。也许这就是造成差异的原因。AFAIK,
a[1://code>将创建一个新列表,如果原始列表非常大,这可能会导致很大的开销。我已经用
islice
测试了你的代码,它的速度和
starmap
方法一样快。有趣的是,你说得对,它确实显著改善了情况。我喜欢这些类型的问题-你学到了很多…我也喜欢它;它使您真正深入研究代码XD.AFAIK,
a[1://code>将创建一个新列表,如果原始列表非常大,这可能会导致大量开销。我已经用
islice
测试了你的代码,它的速度和
starmap
方法一样快。有趣的是,你说得对,它确实显著改善了情况。我喜欢这些类型的问题-你学到了很多…我也喜欢它;它使您真正深入了解代码XD。