如何对对象数组进行分组并将其他键保留在输出中

时间:2016-12-20 08:16:58

标签: python group-by counter

我有以下系列:

library(dplyr)
file0 %>% 
   group_by(id) %>%
   summarise(pages=paste(rle(as.character(site_domain))$values, collapse='_'))

#      id                                   pages
#    <fctr>                                   <chr>
#1      1                   ebay.com_facebook.com
#2      2                                ebay.com
#3      3 auto.com_ebay.com_facebook.com_auto.com
#4      4                   ebay.com_facebook.com
#5      5          ebay.com_facebook.com_auto.com

我希望按array = [ {'key': 'val1', 'another_key': 'a'}, {'key': 'val1', 'another_key': 'a'}, {'key': 'val3', 'another_key': 'c'}, {'key': 'val2', 'another_key': 'd'}, {'key': 'val3', 'another_key': 'c'}, {'key': 'val1', 'another_key': 'a'}, ] 分组对象的数量。 对于上面的示例,我想获得下一个选项之一:

key1

我想使用[ {'val1': 3, 'another_key': 'a'}, {'val3': 2, 'another_key': 'c'}, {'val2': 1, 'another_key': 'd'}, ] [ {'key':'val1', count: 3, 'another_key': 'a'}, {'key':'val3', count: 2, 'another_key': 'c'}, {'key':'val2', count: 1, 'another_key': 'd'}, ] 模块。

我的代码:

Counter

但我只得到第一把钥匙......

from collections import Counter 

groups = Counter([a['key'] for a in array])
groups = groups.most_common()

如何获得上述格式之一的另一个键?

4 个答案:

答案 0 :(得分:1)

由于没有回答给你你要求的输出格式,你在这里:

counter = Counter((item['key'], item['another_key']) for item in array)
groups = [{t[0]: count, 'another_key': t[1]} for t, count in counter.most_common()]

此解决方案为您提供了您建议的第一种答案格式。

可以通过以下方式获得第二种格式:

groups = [{'count': count, 'key': t[0], 'another_key': t[1]} for t, count in counter.most_common()]

如稍后发布的@PM 2Ring,如果您不需要,则可以将counter.most_common()换成counter.items()

答案 1 :(得分:1)

只需将要保留的密钥放入可清洗的集合中;一个元组是完美的。然后,您可以通过迭代计数器中的元组和相关计数来轻松构建新的dicts。

from collections import Counter
from pprint import pprint

arr = [
  {'key': 'val1', 'another_key': 'a'},
  {'key': 'val1', 'another_key': 'a'},
  {'key': 'val3', 'another_key': 'c'},
  {'key': 'val2', 'another_key': 'd'},
  {'key': 'val3', 'another_key': 'c'},
  {'key': 'val1', 'another_key': 'a'},
]

groups = Counter((d['key'], d['another_key']) for d in arr)

new_arr = [{'key': t[0], 'another_key': t[1], 'count': val} 
    for t, val in groups.items()]

pprint(new_arr)

<强>输出

[{'another_key': 'd', 'count': 1, 'key': 'val2'},
 {'another_key': 'a', 'count': 3, 'key': 'val1'},
 {'another_key': 'c', 'count': 2, 'key': 'val3'}]

如果您希望列表按计数的降序排序,那么您可以使用Counter.most_common方法:

ordered = [{'key': t[0], 'another_key': t[1], 'count': val} 
    for t, val in groups.most_common()]
pprint(ordered)    

<强>输出

[{'another_key': 'a', 'count': 3, 'key': 'val1'},
 {'another_key': 'c', 'count': 2, 'key': 'val3'},
 {'another_key': 'd', 'count': 1, 'key': 'val2'}]

答案 2 :(得分:0)

counter = Counter([tuple(a.items()) for a in array])
print(counter)
for tup, count in counter.items():
    print('-----')
    print(tup)
    print(tup[0][1])
    d = dict(tup)
    print(d)
    print(d['another_key'])
    print(count)

结果:

Counter({(('another_key', 'a'), ('key', 'val1')): 3, (('another_key', 'c'), ('key', 'val3')): 2, (('another_key', 'd'), ('key', 'val2')): 1})
-----
(('another_key', 'c'), ('key', 'val3'))
c
{'another_key': 'c', 'key': 'val3'}
c
2
-----
(('another_key', 'a'), ('key', 'val1'))
a
{'another_key': 'a', 'key': 'val1'}
a
3
-----
(('another_key', 'd'), ('key', 'val2'))
d
{'another_key': 'd', 'key': 'val2'}
d
1

答案 3 :(得分:-1)

为您的理解添加更多内容:

groups = Counter(a[key] for a in array for key in a)

它可以是生成器表达式而不是列表理解。