如何在Python中压缩数组?
有没有办法在Python中“压缩”一个数组,让它保持相同的范围,但元素的数量减少到一个指定的值呢?
比如说,我有一个包含1000个元素的数组,我想把它修改成只有100个元素。具体来说,我有一个numpy数组是这样的:
x = linspace(-1,1,1000)
但是因为我在项目中使用它的方式,我不能简单地用linspace重新创建它,因为它不总是在-1到1的范围内,并且有1000个元素。这些参数会变化,而我在定义的函数中无法访问它们。所以我需要一种方法来压缩这个数组,同时保持-1到1的映射。可以把它想象成降低数组的“分辨率”。有没有什么内置的函数或者其他库可以做到这一点呢?
2 个回答
1
你可以随机选择一些项目,这样可以减少你在缩减数据时可能产生的偏见。如果原始样本是无序的,那么你只需要这样做:
import random
sample = range(1000)
def reduce(sample, count):
work = sample[:]
random.shuffle(work)
return work[:count]
如果顺序很重要,那就用枚举来跟踪位置,然后再把它们组合起来。
def reduce(sample, count):
indexed = [item for item in enumerate(sample)]
random.shuffle(indexed)
trimmed = indexed[:count]
trimmed.sort()
return [item for index,item in trimmed]
3
一种简单的“重采样”数组的方法是把它分成几个小块,然后对每个小块求平均值:
(分块的函数来自于这个回答)
# Chunking function
def chunks(l, n):
for i in xrange(0, len(l), n):
yield l[i:i+n]
# Resampling function
def resample(arr, newLength):
chunkSize = len(arr)/newLength
return [np.mean(chunk) for chunk in chunks(arr, chunkSize)]
# Example:
import numpy as np
x = np.linspace(-1,1,15)
y = resample(x, 5)
print y
# Result:
# [-0.85714285714285721, -0.4285714285714286, -3.7007434154171883e-17, 0.42857142857142844, 0.8571428571428571]
你可以看到,重采样后的数组范围会向内缩小,但对于更大的数组,这种效果会小很多。
我不太确定这些数组是否总是由numpy.linspace
生成。如果是的话,还有更简单的方法,比如直接选择原数组中的每第n个元素,其中n是由“压缩”比例决定的:
def linearResample(arr, newLength):
spacing = len(arr) / newLength
return arr[::spacing]