groupby用于多列不带熊猫的列表的字典

时间:2020-07-30 01:10:20

标签: python list dictionary group-by

我正在研究一个不使用熊猫即可处理数据的问题。 我使用列表数据字典读取CSV数据。

product year  complaints
'A'     2002  'bla'
'A'     2003   ''
'B'     2003   ''
'C'     2004  'blabla'

数据看起来像

data = {'product': ['A', 'A', 'B', 'C'],
'year':[2002, 2003, 2003, 2004]
'complaints': ['bla', '', '', 'blabla']
}

如何根据这样的年份和产品创建分组表?

product year  total_complaints
A       2002   1
A       2003   0
B       2003   0
C       2004   0

4 个答案:

答案 0 :(得分:0)

使用嵌套字典快速将计数表制成表格。内置的defaultdict使得这一操作非常容易。

from functools import partial
from collections import defaultdict
d = defaultdict(partial(defaultdict, lambda *args, **kwargs: 0))
for row in records:
    product = row.get('product', None)
    if product is not None:
        pd = d[product]
        year = row.get('year', None)
        if year is not None:
            pd[year] += 1
print(d)

答案 1 :(得分:0)

我建议将您保存数据的方式更改为如下形式:

data = {
    'A': { '2002': ['bla'], '2003': [] },
    'B': { '2003': [] },
    'C': { '2004': ['blablabla'] },
}

然后显示按投诉分组的表格:

for product, years in data.items():
    for year, complaints in years.items():
        print(f'{product}\t{year}\tlen(complaints)')

答案 2 :(得分:0)

此代码使用(产品,年份)作为关键字来创建字典:

data = {'product': ['A', 'A', 'B', 'C'],
'year':[2002, 2003, 2003, 2004],
'complaints': ['bla', '', '', 'blabla']
}

# convert dictionaries to array
dd = list(zip(data['product'], data['year'], data['complaints']))

# distinct keys
keys = set(zip(data['product'], data['year']))

# totals storage
ttl = {x:0 for x in keys}

# Tally totals by key (product\year)
for d in dd:   
    ttl[(d[0],d[1])] += 1 if d[2] else 0

print (ttl)

输出

{('A', 2003): 0, ('B', 2003): 0, ('C', 2004): 1, ('A', 2002): 1}

答案 3 :(得分:0)

DataFrame GroupBy有效地从作为参数提供的列/字段中创建逻辑(哈希)键。下面的方法通过使用定义的定界符构造一个唯一的字符串来“手动”创建逻辑密钥,从而人为地复制了该方法。然后,使用逻辑键使用字典来聚合计数。 (注意:这种逻辑结构很简单。它并不完美。例如,如果您的产品包含“ ::”定界符,它将失败。有多种方法可以解决此问题;字典支持元组键...)

如果期望具有表格输出,则必须执行第二步来解构键并展平结构。下面我提供了一个示例,说明如何创建元组列表(即DataFrame输入)。

agg_res = {} 
for (prod, yr, comp) in zip(data["product"], data["year"], data["complaints"]):
    count = 1
    if comp is None or comp == "":
        count = 0
    prod_yr = "{0}::{1}".format(prod, yr)
    if prod_yr not in agg_res.keys():
        agg_res[prod_yr] = count
    else:
        agg_res[prod_yr] += count
tbl = []
for k, v in agg_res.items():
    a = k.split("::")
    tbl.append( (a[0], int(a[1]), v) )

在您的示例中,具有空字符串的组仍然存在且计数为零。那是故意的吗?