繁体   English   中英

在Python中调整数据序列大小的最佳方法

[英]Best way to resize a data sequence in Python

我有一个必须调整大小的数据序列(列表)。 我已经为它编写了一个函数,但是它非常粗糙。 有谁知道解决这个问题的更好方法?

预期的行为:

在所有示例中,我的输入数据序列如下:编辑:即使示例是线性的,您也不能指望该序列是由公式构建的。

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

当我将其大小从10个项目调整为5个时,我希望得到类似以下输出的内容:

[1, 3, 5, 7, 9][2, 4, 6, 8, 10]

现在,当您将数据序列的长度减少一半时,这并不是很困难,但是我的输出序列的大小是可变的。 我可以小于或大于原始序列的长度。

当我将其大小从10个调整为19个(手动进行简单的编号)时,我期望这样的事情:

[1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10]

当前功能

def sequenceResize(source, length):
    """
    Crude way of resizing a data sequence.
    Shrinking is here a lot more accurate than expanding.
    """
    sourceLen = len(source)
    out = []
    for i in range(length):
        key = int(i * (sourceLen / length))
        if key >= sourceLen:
            key = sourceLen - 1

        out.append(source[key])
    return out

结果如下:

>>> sequenceResize(sequence, 5)
[1, 3, 5, 7, 9]
>>> sequenceResize(sequence, 19)
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10]

收缩是准确的,但扩展顺序并不是那么好。

有谁知道适当解决此问题的现有或简单方法?

您可以使用np.lisnpace:

import numpy as np

list_in = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

resize = 19

list_out = np.linspace(list_in[0], list_in[-1], num=resize)

print(np.ndarray.tolist(list_out))

输出:

[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]

而不是直接确定索引,您应该计算两个列表中索引之间的“步长”比率。 请注意,步骤少于列表中的元素。 然后,您可以获取floorceil项,并根据当前步骤的小数部分确定最终值,获得两者之间的加权平均值(请参见下图)。

def sequenceResize(source, length):
    step = float(len(source) - 1) / (length - 1)
    for i in range(length):
        key = i * step
        low = source[int(math.floor(key))]
        high = source[int(math.ceil(key))]
        ratio = key % 1
        yield (1 - ratio) * low + ratio * high

或更短一点,使用divmod

def sequenceResize(source, length):
    step = float(len(source) - 1) / (length - 1)
    for i in range(length):
        low, ratio = divmod(i * step, 1)
        high = low + 1 if ratio > 0 else low
        yield (1- ratio) * source[int(low)] + ratio * source[int(high)]

例子:

>>> sequence = [1, 2, 4, 8, 16]
>>> list(sequenceResize(sequence, 5))
[1, 2.0, 4.0, 8.0, 16.0]
>>> list(sequenceResize(sequence, 3))
[1, 4.0, 16.0]
>>> list(sequenceResize(sequence, 10))
[1, 1.44444, 1.88889, 2.66667, 3.55556, 4.88889, 6.66667, 8.88889, 12.44444, 16.0]
>>> list(sequenceResize(sequence, 19))
[1, 1.22222, 1.44444, 1.66667, 1.88889, 2.22222, 2.66667, 3.11111, 3.55556, 4.0, 4.88889, 5.77778, 6.66667, 7.55556, 8.88889, 10.66667, 12.44444, 14.22222, 16.0]

一个不同的例子作为说明。 蓝色是原始值,红色是内插值。

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM