两个 Python 列表的匹配长度
Match length of two Python lists
我有两个 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 用户可以详细说明解决此任务的替代方法,我将不胜感激。
非常感谢任何回答或评论。
这是代码的简化版本(不一定具有更好的性能):
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
循环可能会提高性能,因为这样您就不必 "jump"将被丢弃:
new_a = []
jump = len(b)
index = 0
for i in range(jump):
new_a.append(a[index])
index += jump
a = new_a
如果要遍历列表,可以使用生成器,这样就不必将整个内容复制到内存中。
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
#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 的多余部分,因此列表的大小应该相同。这个 returns 作为 [a, b]
所以我们然后解压到各自的变量 (a, b = ...
).
见
https://www.programiz.com/python-programming/methods/built-in/zip 有关 zip 的更多信息并将其用作自己的反函数
首先,为了提高性能,您应该使用 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
我有两个 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 用户可以详细说明解决此任务的替代方法,我将不胜感激。
非常感谢任何回答或评论。
这是代码的简化版本(不一定具有更好的性能):
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
循环可能会提高性能,因为这样您就不必 "jump"将被丢弃:
new_a = []
jump = len(b)
index = 0
for i in range(jump):
new_a.append(a[index])
index += jump
a = new_a
如果要遍历列表,可以使用生成器,这样就不必将整个内容复制到内存中。
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
#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 的多余部分,因此列表的大小应该相同。这个 returns 作为 [a, b]
所以我们然后解压到各自的变量 (a, b = ...
).
见 https://www.programiz.com/python-programming/methods/built-in/zip 有关 zip 的更多信息并将其用作自己的反函数
首先,为了提高性能,您应该使用 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