如何在Python中压缩数组?

4 投票
2 回答
6239 浏览
提问于 2025-04-20 07:55

有没有办法在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]

撰写回答