6

我有一个浮点数列表,我想从我的第一个列表中生成另一个周期回报列表。

这是工厂实施的运行(未经测试 - 显然没有错误检查/处理):

a = [100,105,100,95,100]

def calc_period_returns(values, period):
    output = []
    startpos, endpos = (period, len(values)-1)

    while True:
        current = values[startpos]
        previous = values[startpos-period]
        ret = 100*((current-previous)/(1.0*previous))
        output.append(ret)
        startpos += period
        if startpos > endpos:
            break
    return output


calc_period_returns(a,1)

# Expected output:
# [5.0, -4.7619047619047619, -5.0, 5.2631578947368416]

有没有更 Pythonic 的方式来做到这一点 - 也许使用列表理解和地图?

4

4 回答 4

20

我不知道你的数字列表会有多大,但如果你要处理大量的数字,你应该看看 numpy. 副作用是计算看起来要简单得多。

使用 numpy,您可以为数据创建一个数组

>>> import numpy as np
>>> a = np.array([100,105,100,95,100], dtype=float)

并像使用简单数字一样处理数组

>>> np.diff(a) / a[:-1] * 100.
[ 5.         -4.76190476 -5.          5.26315789]
于 2012-04-19T11:19:53.417 回答
12

干得好:

>>> [100.0 * a1 / a2 - 100 for a1, a2 in zip(a[1:], a)]
[5.0, -4.7619047619047592, -5.0, 5.2631578947368354]

由于您想比较列表的相邻元素,您最好创建一个您感兴趣的对列表,如下所示:

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
>>> zip(a, a[1:])
[(0, 1), (1, 2), (2, 3), (3, 4)]

之后,从一对数字中提取百分比变化只是一个简单的数学运算。

于 2012-04-19T11:04:31.827 回答
2

谢谢你们的回答!如果有人只想复制粘贴(如我),我根据您的回答实现了一个功能:

def pct_change(nparray):
    pct=np.zeros_like(nparray)
    pct[1:]=np.diff(nparray) / np.abs(nparray[:-1])
    #TODO zero divisionerror
    return pct
于 2020-05-05T23:23:55.507 回答
0

你也可以这样做:

>>> a = [100,105,100,95,100]
>>> [(a[i]-a[i-1])/a[i-1] for i in range(1, len(a))]
[0.05, -0.047619047619047616, -0.05, 0.05263157894736842]
于 2021-05-13T19:17:21.207 回答