【问题标题】:How do I achieve the proper output for this dataset?如何为该数据集实现正确的输出?
【发布时间】:2012-01-17 18:44:07
【问题描述】:

我在从数据集中获取正确输出时遇到问题。

我有一个包含股票代码名称、权重和分数的数据集,我想提取一个唯一的 TIK、权重、分数列表,其中分数 = 给定股票代码的 MAX(score)。

数据集的一个例子是

[(u'COOL ', 25, 452.50000000000006), (u'MIND', 25, 221), (u'SIMO', 25, 209), (u'RAVN', 25, 131.75), (u'AET', 25, 99), (u'SBUX', 25, 83.5), (u'ATVI', 25, 47.75), (u'CACI', 25, 45.5), (u'DISH ', 25, 17.25), (u'COOL ', 15, 271.5), (u'MIND', 15, 132.6), (u'SIMO', 15, 125.39999999999999), (u'RAVN', 15, 79.05), (u'AET', 15, 59.4), (u'SBUX', 15, 50.099999999999994), (u'ATVI', 15, 28.65), (u'CACI', 15, 27.3), (u'DISH ', 15, 10.35), (u'COOL ', 10, 181), (u'MIND', 10, 88.4), (u'SIMO', 10, 83.6), (u'RAVN', 10, 52.699999999999996), (u'AET', 10, 39.6), (u'SBUX', 10, 33.4), (u'ATVI', 10, 19.099999999999998), (u'CACI', 10, 18.2), (u'DISH ', 10, 6.8999999999999995), (u'COOL ', 5, 90.5), (u'MIND', 5, 44.2), (u'SIMO', 5, 41.8), (u'RAVN', 5, 26.349999999999998), (u'AET', 5, 19.8), (u'SBUX', 5, 16.7), (u'ATVI', 5, 9.549999999999999), (u'CACI', 5, 9.1), (u'DISH ', 5, 3.4499999999999997)]

.....对于数据集中的每个股票代码。

而我希望达到的结果是:

COOL 25 452.50
MIND 15 132.6
SIMO 10 83.6

例如。 AAPL 的权重为 25,TITN 的权重为 20,ANF 的权重为 15,其相关分数的权重为 15,直到 sum(weight) = 100。

对于给定的重量,每个代码只能报告一次。因此,如果 AAPL 在权重 25 处得分最高,则不能在任何其他权重处再次使用它。

这很难解释,希望我已经为你们提供了足够的指导。

***为了更清楚,附加了一些真实的样本数据

【问题讨论】:

  • 你的输出正确吗?因为300 不是TITN 代码之间的最高分

标签: python


【解决方案1】:
>>> from itertools import groupby
>>> 
>>> groups = groupby(table, lambda x: x[0])     # table not sorted because items already are
>>> [max(item[1], key=lambda x:x[2]) for item in groups]
[('AAPL', 25, 400), ('TITN', 25, 350), ('ANF', 25, 250)]
>>> 

或分两行(只是为了好玩,抱歉):

>>> from itertools import groupby
>>> [max(item[1], key=lambda x:x[2]) for item in groupby(table, lambda x: x[0])]
[('AAPL', 25, 400), ('TITN', 25, 350), ('ANF', 25, 250)]

编辑:考虑到新表和 OP 给出的示例,我理解必须在每个步骤中优先考虑表中可用的有效最大值进行分析选择。然后使用:

table = [(u'COOL ', 25, 452.5), (u'MIND', 25, 221),
         (u'SIMO', 25, 209), (u'RAVN', 25, 131.75), (u'AET', 25, 99),
          .............................
         (u'CACI', 5, 9.1), (u'DISH ', 5, 3.45)]

while table:
    maxim = max(table, key= lambda x:x[2])
    print maxim
    table = [tup for tup in table if tup[1] != maxim[1] and tup[0] != maxim[0]]

打印出来:

(u'COOL ', 25, 452.5)
(u'MIND', 15, 132.59999999999999)
(u'SIMO', 10, 83.599999999999994)
(u'RAVN', 5, 26.350000000000001)

请注意,根据您连续选择项目所遵循的规则,结果会有所不同(请参阅下面的评论)。上面代码中选择的条件是给出更接近 OP 的结果的条件。我的答案中的附加术语可能对应于 OP 示例中的错误

【讨论】:

  • 非常感谢 joaquin,我将在我的真实数据集上测试这个场景并确认它!
  • joaquin,是否可以进行调整以返回每个代码的唯一重量?请注意输出中的所有代码如何具有相同的权重,这应该根据分数递减。所以AAPL的权重是25,TITN的权重是20,ANF的权重是15
  • 我不确定你的意思。如果您的意思是 25 应该只在一个元组中,那么这意味着没有唯一的答案。如果我首先得到 ('AAPL', 25, 400) ,那么其他两个元组都不会成为结果的一部分。但是如果我先选择 ('ANF', 25, 250),那么 ('AAPL', 25, 400) 就不会出现在结果中。那是你需要的吗?关于如何选择结果还有其他条件吗?
  • 我认为我的数据集需要简化。将每个权重值分配给每个符号没有任何好处,它实际上使问题复杂化。
【解决方案2】:

好吧,不使用一些额外的库,这可以如下完成:

def get_element(lst, key):
  for obj in lst:
    if key(obj):
      return obj
  return None

def generate_list(data_set):
  result = []
  for obj in data_set:
    temp = get_element(result, lambda k: k[0] == obj[0])
    if temp is None:
      result.append(obj)
    elif obj[1] > temp[1]:
      ind = result.index(temp)
      result[ind] = obj      
  return result

这会产生与您的输入相同的列表格式。

【讨论】:

  • 非常感谢怪胎!我将根据我的真实数据集对此进行测试。感谢您提供不使用库的方法!
【解决方案3】:

许多有效的答案。我的回答侧重于开发人员的可读性:

from collections import namedtuple

Share = namedtuple('Share', 'name weight score')
d = {}
for share in [Share(*i) for i in table]:
    try:
        d[share.name] = share if share.score > d[share.name][2]\
                              else d[share.name]    
    except KeyError:
        d[share.name] = share

for share in d:
    print repr(d[share][:]).strip('()')

>>> 'AAPL', 25, 400
>>> 'TITN', 25, 350
>>> 'ANF', 25, 250

在您的表格中,权重似乎已经集成到分数中,因为每个权重点似乎代表 10 个分数点,并且权重和分数之间存在直接相关性。

【讨论】:

  • 不需要任何计算,只是想找到一个唯一的行列表,其中选择了特定权重得分最高的行情,并且每个权重仅使用一次。所以数据集中会有很多代码,但我只想显示特定重量的最佳代码。
  • tik & weight 组合的最高分。最终目标是提供一个按分数加权的股票列表,并且一只股票只能被引用一次……所以“得分最高”的股票应该是与最高权重相关的股票。感谢您的帮助先生!
  • 唐,似乎所有代码都以相同的权重返回,这可以根据分数减少吗?所以 AAPL 的权重为 25,TITN 的权重为 20,ANF 的权重为 15,其相关分数的权重为 15?
【解决方案4】:

大家好,感谢您的反馈!我从你的意见中意识到我需要在这个过程中退后一步。

与将每个权重分配给每个代码并尝试查询该数据集相反,我根据其总体得分为代码分配了唯一权重。

*这使用了一个已经按最高分排序的数据集。

x = (25, 20, 15, 10, 10, 10, 5, 5)
y = 0
for each in table:
    if y > 7:
        pass
    else:
        w = each[0], each[1], each[2], x[y]
        print w
        y += 1

感谢您的指导!为了您的麻烦,这些是一些优质的股票...

(u'COOL ', 2.98, 0.54, 25)
(u'MIND', 23.96, 2.12, 20)
(u'SIMO', 22.35, 1.87, 15)
(u'RAVN', 65.35, 3.45, 10)
(u'AET', 43.93, 1.74, 10)
(u'SBUX', 47.6, 1.59, 10)
(u'ATVI', 12.56, 0.24, 5)
(u'CACI', 56.96, 1.04, 5)

【讨论】:

  • 您不是在回答自己的原始问题,而是在回答一个从未提出过的问题!。
  • @joaquin 看起来像是我的答案。
  • @Kev 你说了算,但我无法想象如何从两个版本的问题和 OP(他自己)发布的预期结果中得出上述答案......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 2016-09-30
  • 1970-01-01
  • 1970-01-01
  • 2018-04-02
  • 2021-11-11
相关资源
最近更新 更多