【问题标题】:Compute a list of rounded proportions计算四舍五入的比例列表
【发布时间】:2020-11-12 08:29:55
【问题描述】:

必填:

[10,20,-30] -> [1,2,-3]
[19,-14,15] -> [2,-1,2]
[-1.09,-0.92,0.02] -> [-109,-92,2]
[501.6545,-1857.1,897.543] -> [5,-19,9]

每个输入集中最接近零的数字应该是输出中的单个数字。比例必须保持大致恒定,接受舍入误差。

背景:使用尽可能少的订单将要购买的证券股票数量从模型转换为 100 手。

我可以以非 Python 的方式强制执行此操作,但我正在寻找有关要使用的 Python 函数的指针。我的背景是 Java。

【问题讨论】:

  • “个位数”总是为 1 是否可以接受?那么你应该能够轻松解决这个问题。
  • @JanChristophTerasa 最小的数字不能是 1,因为比例会发生剧烈变化,输出必须是整数。
  • 不应该是[-1.09,-0.92,-0.02] -> [-109,-92,-2]吗?
  • @user8408080 好收获

标签: python numpy math scipy finance


【解决方案1】:

在 Python 中,您将使用 numpy 进行此类计算。我会建议这样的算法:

def process(array):
    order_of_magnitude = np.floor(np.log10(np.min(np.abs(array))))
    return np.round(array*10**(-order_of_magnitude))

解释:

  1. 找出数组中最小元素的数量级(不考虑符号)。
  2. 据此缩放(或放大)每个元素。
  3. 四舍五入

您需要为此安装numpy。例如使用 pip 或通过您的 linux 发行版。

像这样把你的列表变成 numpy 数组:

array = np.array(your_list)

【讨论】:

  • 我根据您在满足要求的新答案中发布了代码。 Python 不愿将数组提升为浮点指数,因此我将其转换为 nparray。我还将答案转换为整数。感谢您的帮助,我永远也想不出 Pythonic 的解决方案。
  • @KevinRethwisch 这很有趣,因为我没有收到任何关于将数组提升为浮点指数的警告。您使用的是哪个 numpy 和 python 版本?无论如何,我很高兴能帮上忙!
  • 这很奇怪,因为指数可以是十进制数。这是我的版本:Python 2.7.16 Numpy 1.16.2
  • @KevinRethwisch 哦,这些都是相当旧的版本。我会强烈建议您不要再使用 Python 2,尤其是当您似乎是 Python 初学者时。出于向后兼容性的原因,该软件不再受支持,仅安装在某些 Linux 发行版上。当您在终端中执行python 时,它可能会非常烦人——例如——调用python2 的基于Debian 的系统。在这种情况下,只需键入 python3,您将使用受支持的 python 版本。此外,如果你使用 pip,那么——在那些发行版上——你将不得不使用pip3
  • 我使用 Arch,顺便说一句
【解决方案2】:

忽略您的示例,我实现了要求

每个输入集中最接近零的数字应该是输出中的单个数字。比例必须保持大致恒定,接受舍入误差。

该算法通过最接近零的值的绝对值对数据进行归一化,并将结果乘以 9 以保持最小数字为一位,从而最大限度地减少后续舍入误差。

def normalize(l):
    import numpy as np
    m = np.min(np.abs(l))
    return np.round(l / m * 9).astype(int)

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 此代码回答问题的附加上下文可提高其长期价值.
  • 我不知道为什么你乘以 9 但它会产生不正确的结果。正如您在评论中建议的那样,删除 9 会使比例最小为 1,但也会产生不正确的结果。
  • 您用于生成示例的算法会产生巨大的错误,只需检查[19, -14, 15] 会导致[2, -1, 2]。这将产生更好的结果。
  • 无论哪种方式都会产生巨大的错误。你的例子是书面收益率 [ 9 18 -27] [ 9 -9 9] [-490 -414 9] [ 9 -33 16] 不乘以 9 我们得到 [ 1 2 -3] [ 1 -1 1] [- 54 -46 1] [ 1 -4 2] 两者都不正确。
  • 这正是我们首先乘以 9 的原因,以最小化错误。
【解决方案3】:

这是基于@user8408080 答案的正确答案。

import numpy as np
def process(array):
    order_of_magnitude = np.floor(np.log10(np.min(np.abs(array)))).astype(int).item()
    return np.round(np.asarray(array)*10**(-order_of_magnitude)).astype(int)

【讨论】:

    猜你喜欢
    • 2013-11-19
    • 2014-10-29
    • 2022-01-09
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    相关资源
    最近更新 更多