【问题标题】:Bring all values in an array closer together将数组中的所有值靠得更近
【发布时间】:2016-07-31 13:48:47
【问题描述】:

我需要做的是将 l1 中的值“压碎”某个百分比,以便它们更接近,这样如果数组 l1 可能......

l1 =[10,20,30,40,50,60,70,80,90,100]

那么 l2 可能是...

l2 = [12.5, 25.0, 37.5, 50.0, 62.5, 45.0, 52.5, 60.0, 67.5, 75.0]

这可以通过一个简单的脚本来完成,例如...

for i in l1:
    if i <= 50:
        i = (i*1.25)
        l2.append(i)
        print(i)
    elif i >= 50:
        i = (i*0.75)
        l2.append(i)

print (l2)

这表明我需要将所有项目靠得更近——最好是某个百分位(打印)。当您有这样的列表时会出现问题...

l1 =[4,2,3,4,3,6,4,8.6,10,7,12,4,14,15,26,14,15,16,10]

然后我需要做的是将所有项目离散地放在一起(因此按一定百分比),但在一个循环中。我需要“压缩”或“粉碎”数组的值,将每个数字之间的范围从最小到最大,从最大到最小(更接近中位数)。我不能只除以整个列表,因为范围保持不变。

我认为解决这个问题的一种方法(我现在正在做的工作)是(a)找到 l1 的中位数,(b)从 l1 中最小和最大的项目开始,将该项目增加 10%它的价值或减少其价值的 10%(在最大项目的情况下),然后在同一个循环中处理第二个最小和最大的项目(以避免脚本两次遍历相同的“较小的变量”) .

这意味着从最大到最小列出值,同时保持它们在数组中的位置(这很重要),然后搜索该列表并对数组 l1 的每个对应值进行更改。

对于建议的解决方案的注意......一次迭代......

import statistics
a = [4, 3, 3, 4, 5, 1, 31, 321]
input_scope = 1.1

def scouter (input_list, scope):
    mean = statistics.mean(input_list)
    searchpositions = []
    for x, i in enumerate(input_list):
            print (x, i)
            if i == max(input_list) or i == min(input_list):
                searchpositions.append(x)

    for i in searchpositions:
        input_list[i] = [(input_list[i] - mean) / scope + mean]
    return (input_list)
print(scouter((a), input_scope))

给我我需要的东西,有点......

[4, 3, 3, 4, 5, [5.13636363636364], 31, [296.0454545454545]]

输出是列表中的列表!有没有一种简单的方法可以通过重写函数来消除这种情况?

【问题讨论】:

  • 我不明白你如何从上面的 l1 计算 l2。例如,为什么2 仍然是2
  • 如果您阐明一个好的解决方案需要具备哪些属性,您可能会更容易得到答案。例如,这个更简单的解决方案有什么问题:l2 = [x * 0.01 for x in l1]
  • 如果您的应用程序有错误,您可能希望修复错误而不是尝试解决输入值。
  • 第二个示例的期望输出是什么?
  • 他们真的需要更接近中位数,还是更接近均值也可以?

标签: python arrays algorithm sorting


【解决方案1】:

只向中位数缩放?

>>> l1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

>>> import statistics
>>> median = statistics.median(l1)
>>> [(x - median) / 10 + median for x in l1]
[50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5]

【讨论】:

  • 还没有安装这个模块。让我看看这是如何处理数据的。
  • @mmacheerpuppy 它是在 Python 3.4 中引入的,所以也许是时候更新了? :-)。或者自己做,见the source code。或者,如果您可以使用均值而不是中位数,那当然更简单。
  • 谢谢!适用于一些数据集,但不适用于更大更复杂的数据集(你最终得到的是每个数字最终都等于平均值​​/中位数。有没有办法只针对数组中的最大/最小数字?跨度>
  • @mmacheerpuppy 肯定有办法。但是请举一个每个数字都变成平均值/中位数的例子。
  • 写了我的函数来完成你的建议!但这给了我列表中的列表! :( 我已经将我所做的添加到主体中,供您阅读输出。您能告诉我我做错了什么吗:有没有办法在不创建列表的情况下创建一个函数来执行此操作列表还是我必须展平该列表?
【解决方案2】:

我知道我迟到了,但我确切地知道您需要什么,而且我也有自己使用的解决方案。我想出了这个解决方案:

对于集合中的每个数字 n,您会得到一个新数字 x,它更接近集合的 mean,由此公式:

x = mean + factor * (n - mean)

因子的范围从 0 到 1,表示数字需要向平均值增长或缩小多少。 0 = 所有数字变为平均值,1 = 所有数字保持不变。根据自己的需要进行调整。

集合的平均值显然是集合中每个数字的总和除以集合的长度。

希望这对未来登陆这里的人有所帮助。

【讨论】:

    【解决方案3】:

    为什么不在列表中找到最小的数字,然后将整个列表除以该数字?甚至是您想要的任何数字。

    num = percentage/100 # gets you a decimal
    l2 = [x*num for x in l1]
    

    如果您想这样做,请使用min() 查找列表中的最低编号。

    【讨论】:

    • 不幸的是,这不起作用。我需要从最大和最小的中间向内爬行,或者从中间开始向外爬行。我认为前者会更容易。我已经更新了帖子以更好地说明。
    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多