匹配两个Python列表的长度

时间:2017-08-30 16:23:51

标签: python python-2.7 list numpy signal-processing

我有两个不同长度的Python列表。可以假设其中一个列表比另一个列表大几倍。

两个列表都包含相同的物理数据,但采用不同的采样率进行捕获。

我的目标是对较大的信号进行下采样,使其具有与较小信号一样多的数据点。

我提出了以下代码,它基本上完成了这项工作,但既不是Pythonic,也不能以高效的方式处理非常大的列表:

import math

a = [1,2,3,4,5,6,7,8,9,10]
b = [1,4.5,6.9]

if len(a) > len(b):
    div = int(math.floor(len(a)/len(b)))
    a = a[::div]
    diff = len(a)-len(b)
    a = a[:-diff]
else:
    div = int(math.floor(len(b)/len(a)))
    b = b[::div]
    diff = len(b)-len(a)
    b = b[:-diff]
print a
print b

如果更有经验的Python用户能够详细说明解决此任务的其他方法,我将不胜感激。

我们非常感谢您的回答或评论。

4 个答案:

答案 0 :(得分:1)

这是代码的缩短版本(不一定是更好的性能):

a = [1,2,3,4,5,6,7,8,9,10]
b = [1,4.5,6.9]
order = 0  # To determine a and b.

if len(b) > len(a):
    a, b = b, a  # swap the values so that 'a' is always larger.
    order = 1

div = len(a) / len(b)  # In Python2, this already gives the floor.
a = a[::div][:len(b)]

if order:
    print b
    print a
else:
    print a
    print b

由于您最终丢弃较大列表中的后一些元素,因此显式for循环可能会提高性能,因为您不必“跳转”到将被丢弃的值:

new_a = []
jump = len(b)
index = 0
for i in range(jump):
    new_a.append(a[index])
    index += jump
a = new_a

答案 1 :(得分:1)

首先,对于性能,您应该使用numpy。问题用numpy标记,所以也许你已经,并没有显示它,但无论如何,列表可以转换为numpy数组

import numpy as np
a = np.array(a)
b = np.array(b)

索引是一样的。 可以在数组上使用len,但array.shape更通用,提供以下(非常相似)代码。

 a[::a.shape[0] // b.shape[0]]

性能方面,这应该可以大大提高大多数数据的速度。 使用更大的a和b数组(分别为10e6和1e6元素)进行测试表明,numpy可以大大提高性能。

a = np.ones(10000000)
b = np.ones(1000000)

%timeit a[::a.shape[0] // b.shape[0]]  # Numpy arrays
1000000 loops, best of 3: 348 ns per loop

a = list(a); 
b = list(b);
%timeit a[::len(a) // len(b)]    # Plain old python lists
1000000 loops, best of 3: 29.5 ms per loop

答案 2 :(得分:0)

如果您在列表上进行迭代,则可以使用生成器,这样您就不必将整个内容复制到内存中。

from __future__ import division

a = [1,2,3,4,5,6,7,8,9,10]
b = [1,4.5,6.9]

def zip_downsample(a, b):
    if len(a) > len(b):
        b, a = a, b  # make b the longer list
    for i in xrange(len(a)):
        yield a[i], b[i * len(b) // len(a)]

for z in zip_downsample(a, b):
    print z

答案 3 :(得分:-1)

#a = [1,2,3,4,5,6,7,8,9,10]
#b = [1,4.5,6.9]

a, b = zip(*zip(a, b))

# a = [1, 2, 3]
# b = [1, 4.5, 6.9]

内部zip将列表组合成pars,从较大的列表中丢弃多余的项目,返回[(1, 1), (2, 4.5), (3, 6.9)]之类的内容。然后外部zip执行相反的操作(因为我们用*运算符解包),但由于我们已经丢弃了第一个zip的多余部分,因此列表应该是相同的大小。这将返回[a, b],因此我们将解压缩到相应的变量(a, b = ...)。

请参阅 https://www.programiz.com/python-programming/methods/built-in/zip了解有关zip的更多信息,并将其作为自己的逆转