【问题标题】:Group data into specified intervals satisfying certain condition将数据分组到满足特定条件的指定区间
【发布时间】:2012-10-28 16:13:24
【问题描述】:

我想将此列表中的这些项目分类到新列表中...

truc = [['12', 'brett', 5548],
       ['22.3', 'troy', 9514],
       ['8.1', 'hings', 12635],
       ['34.2', 'dab', 17666],
       ['4q3', 'sigma', 18065],
       ['4q3', 'delta', 18068]]

... 使用最后一个字段将它们分组到大小为 3500 的箱中 所以,理想的结果是这样的:

firstSort = [['34.2', 'dab', 17666],
            ['4q3', 'sigma', 18065],
            ['4q3', 'delta', 18068]]

secondSort = [['22.3', 'troy', 9514],
             ['8.1', 'hings', 12635]]

lastSort = ['12', 'brett', 5548]

我尝试使用 itertools.groupby() 函数,但无法找到指定 bin 大小的方法。

【问题讨论】:

  • 是的,你是对的。我的意思是垃圾箱的大小为 3500。我将进行编辑。谢谢!
  • 如果最后一个字段的值是 0、3000 和 6000,那将是什么配对? [0,3000], [6000],或[0], [3000,6000],或[0,3000,6000]
  • 指定一个返回键除以3500的整数结果的函数就够了吗?不过,这可能会以不太理想的方式对项目进行分组。
  • @jwpat7:你不认为他只是错误地输入了 180688 而不是 18068,如果你看一下其他值,这会合乎逻辑吗?
  • @BrtH 是的,就是这样......

标签: python group-by itertools


【解决方案1】:

如果没有 itertools,这很简单

truc = [['12', 'brett', 5548],
       ['22.3', 'troy', 9514],
       ['8.1', 'hings', 12635],
       ['34.2', 'dab', 17666],
       ['4q3', 'sigma', 18065],
       ['4q3', 'delta', 18068]]

truc.sort(key=lambda a:a[-1])
groups = [[]]
last_row = None
for row in truc:
    if last_row is not None and row[-1] - last_row[-1] > 3500:
        groups.append([])
    last_row = row
    groups[-1].append(row)

import pprint
pprint.pprint(groups)

输出:

[[['12', 'brett', 5548]],
 [['22.3', 'troy', 9514], ['8.1', 'hings', 12635]],
 [['34.2', 'dab', 17666], ['4q3', 'sigma', 18065], ['4q3', 'delta', 18068]]]

【讨论】:

  • 不完全是我想要做的,但它可能会给出一个很好的提示。
【解决方案2】:

带有groupby的基本binner:

from itertools import groupby
from math import floor

# data must be sorted

data = [ ['12', 'brett', 5548],
       ['22.3', 'troy', 9514],
       ['8.1', 'hings', 12635],
       ['34.2', 'dab', 17666],
       ['4q3', 'sigma', 18065],
       ['4q3', 'delta', 18068] ]

groups = []
for k, g in groupby(data, lambda x: floor(x[-1]/3500)):
    groups.append(list(g))

print groups

返回:

[
    [
        ['12', 'brett', 5548]
    ],
    [
        ['22.3', 'troy', 9514]
    ],
    [
        ['8.1', 'hings', 12635]
    ],
    [
        ['34.2', 'dab', 17666],
        ['4q3', 'sigma', 18065],
        ['4q3', 'delta', 18068]
    ]
]

当一个组的最大值减去之前组的最小值小于 3500 时,您可以合并这些组。然后您会得到,

[
    [
        ['12', 'brett', 5548]
    ],
    [
        ['22.3', 'troy', 9514],
        ['8.1', 'hings', 12635]
    ],
    [
        ['34.2', 'dab', 17666],
        ['4q3', 'sigma', 18065],
        ['4q3', 'delta', 18068]
    ]
]

即使在groupby 之后进行合并,我认为 Anurag Uniyal 的解决方案在一般情况下仍然可以实现更好的分组。

【讨论】:

    【解决方案3】:

    使用defaultdict():

    lis=[['12', 'brett', 5548],
          ['22.3', 'troy', 9514],
          ['8.1', 'hings', 12635],
          ['34.2', 'dab', 17666],
          ['4q3', 'sigma', 18065],
          ['4q3', 'delta', 18068]]
    
    from collections import defaultdict
    d=defaultdict(list)
    for i,x in enumerate(lis):
        not_append=True
        for y in d:
            for z in d[y]:
                if abs(z[-1]-x[-1])<=3500:
                    d[y].append(x)
                    not_append=False
                    break
        else:
            if not_append:
                d[i].append(x)
    print d.values()
    

    输出:

    [[['12', 'brett', 5548]],
     [['22.3', 'troy', 9514], ['8.1', 'hings', 12635]], 
     [['34.2', 'dab', 17666], ['4q3', 'sigma', 18065], ['4q3', 'delta', 18068]]
    ]
    

    【讨论】:

      猜你喜欢
      • 2013-03-05
      • 2019-06-05
      • 2011-07-10
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多