如何在2D python数组中合并重复项

时间:2009-11-18 21:55:07

标签: python arrays merge duplicates

我有一组类似的数据:

#  Start_Time    End_Time      Call_Type  Info 
1  13:14:37.236  13:14:53.700  Ping1      RTT(Avr):160ms
2  13:14:58.955  13:15:29.984  Ping2      RTT(Avr):40ms
3  13:19:12.754  13:19:14.757  Ping3_1    RTT(Avr):620ms
3  13:19:12.754                Ping3_2    RTT(Avr):210ms
4  13:14:58.955  13:15:29.984  Ping4      RTT(Avr):360ms
5  13:19:12.754  13:19:14.757  Ping1      RTT(Avr):40ms
6  13:19:59.862  13:20:01.522  Ping2      RTT(Avr):163ms
...

当我解析它时,我需要合并Ping3_1Ping3_2的结果,取这两行的平均值,并将其导出为一行,因此结果的结尾将是像这样:

#  Start_Time    End_Time      Call_Type  Info 
1  13:14:37.236  13:14:53.700  Ping1      RTT(Avr):160ms
2  13:14:58.955  13:15:29.984  Ping2      RTT(Avr):40ms
3  13:19:12.754  13:19:14.757  Ping3      RTT(Avr):415ms
4  13:14:58.955  13:15:29.984  Ping4      RTT(Avr):360ms
5  13:19:12.754  13:19:14.757  Ping1      RTT(Avr):40ms
6  13:19:59.862  13:20:01.522  Ping2      RTT(Avr):163ms
...

目前,我正在连接第0列和第1列以创建一个唯一键,在那里找到重复项,然后对那些并行ping执行其余的特殊处理。它根本不优雅。只是想知道什么是更好的方法。谢谢!

3 个答案:

答案 0 :(得分:1)

假设您的副本相邻(因为它们显示在您的问题中),itertools.groupby是将它们标识为重复项的理想方式(在operator.itemgetter的一些帮助下提取“密钥”定义身份。假设您有一个包含.start.end等属性的对象列表(

):

import itertools
import operator

def merge(listofpings):
  k = operator.itemgetter('start', 'end')
  for i, grp in itertools.groupby(listofpings, key=k):
    lst = list(grp)
    if len(lst) > 2:
      item = mergepings(lst)
    else:
      item = lst[0]
    emitping(i, item)

假设您已经有函数mergepings来合并>列表1个“重复”ping,emitping发出编号ping(裸或合并)。

如果listofpings尚未正确排序,只需在listofpings.sort(key=k)循环之前添加for(可能按排序顺序发出正确,对吗?)。

答案 1 :(得分:0)

假设重复项是相邻的,您可以使用这样的生成器。我猜你已经有了一些平均值的代码

def average_pings(ping1, ping2):
    pass

def merge_pings(seq):
    prev_key=prev_key=None
    for item in seq:
        key = item.split()[:2]
        if key == prev_key:
            yield average_pings(prev_item, item)
        else:
            yield item
        prev_key=key
        prev_item=item

答案 2 :(得分:0)

我不确定你的数据是如何构建的,因此我将假设一个用于鸭子打字的dicts列表。

我还假设数据集的真正主键是Start。

for i in range(len(dataset)-1):
  #Detect duplicates, assuming they are sorted properly
  if dataset[i]["Start"] == dataset[i+1]["Start"]:
    #Merge 'em
    dataset[i+1] = merge(dataset[i], dataset[i+1])

    #Deleting items from the array you are iterating over is a bad idea
    dataset[i] = None

dataset = [item for item in dataset if item != None] #so just delete them later

...合并将是实际进行合并的函数。

不优雅,C-ish,但可能比你目前使用的更好。

他们没有排序?

dataset.sort( (lambda x,y: return cmp(x["Start"],y["Start"])) )

现在他们应该。