Python json数据的嵌套计数器

Python json数据的嵌套计数器,python,json,datetime,Python,Json,Datetime,我的JSON数据如下所示: { "persons": [ { "city": "Seattle", "name": "Brian" "dob" : "19-03-1980" }, { "city": "Amsterdam", "name": "David" "dob" : "19-09-197

我的JSON数据如下所示:

{
    "persons": [
        {
            "city": "Seattle", 
            "name": "Brian"
            "dob" : "19-03-1980"
        }, 
        {
            "city": "Amsterdam", 
            "name": "David"
            "dob" : "19-09-1979"
        } 
       {
            "city": "London", 
            "name": "Joe"
            "dob" : "19-01-1980"
        }
        {
            "city": "Kathmandu", 
            "name": "Brian"
            "dob" : "19-03-1980"
        }
   ]
}
我如何在一次迭代中使用python计算单个元素,例如,在1-12月出生的人数(如果没有出生,则为0)和在给定年份出生的人数。以及每月注册的唯一名称的数量 比如:

姓名:

Mar 1980: 1 #Brian is same for both cities 
Jan 1980: 1
Sep 1979: 1
计数器\u mon是具有一年中特定月份值的计数器

for k_mon,v_mon in counters_mon.items():
    print('{}={}'.format(k_mon,v_mon))  
但我也希望打印详细信息。我怎样才能做到这一点

import json    

f = open('/path/to/your/json', 'r')
persons = json.load(f)
years_months = {}
years_months_names = {}

for person in persons['persons']:
    year = person['dob'][-4:]
    month = person['dob'][3:5]
    month_year = month + ' ' + year
    name = person['name']

    if year not in years_months.keys():
        years_months[year] = { 'count': 1, 'months' : {} }
        if month not in years_months[year]['months'].keys():
            years_months[year]['months'][month] = 1
        else:
            years_months[year]['months'][month] += 1
    else:
        years_months[year]['count'] += 1
        if month not in years_months[year]['months'].keys():
            years_months[year]['months'][month] = 1
        else:
            years_months[year]['months'][month] += 1

    if month_year not in years_months_names.keys():
        years_months_names[month_year] = set([name])
    else:
        years_months_names[month_year].add(name)

for k, v in years_months.items():
    print(k + ': ' + str(v['count']))
    for month, count in v['months'].items():
        print("-- " + str(month) + ": " + str(count))
for k, v in years_months_names.items():
    print(k + ": " + str(len(v)))

我假设您有json的路径。我还在您发布的JSON上测试了我的答案,并小心确保您的JSON结构正确。

这是使用defaultdicts()的好例子

根据数据将如何使用,我实际上会考虑在聚合中没有复杂的嵌套,而是选择诸如“代码>聚合[ [年,月] ] = [ NAME1,NAME2,…] < /代码>之类的选项。我发现,我的数据越嵌套,处理起来就越混乱

或者,您可以在第一次通过时创建多个结构,以简化打印步骤。我再次使用
defaultdict
清理所有的资源调配

agg_years = defaultdict(lambda:defaultdict(int))   # [year][month] = counter
agg_years_total = defaultdict(int)   # [year] = counter
agg_months_names = defaultdict(set)   # [(year, month)] = set(name1, name2...)

for person in data['persons']:
    day, month, year = map(int, person['dob'].split('-'))

    agg_years[year][month] += 1
    agg_years_total[year] += 1
    agg_months_names[(year, month)].add(person['name'])


for year, months in sorted(agg_years.items()):
    print('{}: {}'.format(year, agg_years_total[year]))
    for month, quant in sorted(months.items()):
        print('--{}: {}'.format(month_abbr[month], quant))

for (year, month), names in sorted(agg_months_names.items()):
    print('{} {}: {}'.format(month_abbr[month], year, len(names)))

首先,您的json无效(),因为您可以调用
计数器\u mon.items()
,您可能正在使用字典。好的,首先我提取了值并将其添加到列表中,然后对其执行操作。~感谢您的回答,我将在办公系统中进行尝试,如果有什么,请返回。~接受了答案,但它没有显示1979年9月的计数,并且给出了3月计数为1,但实际上是1980年的2。检查JSON的结构。我刚刚用上面的代码再次测试了它,结果是正确的。我也在运行Python 3。它还将显示月份号,而不是月份名称。1979:1 1980:3--03:1--01:1 03 1980:1 09 1979:1 01 1980:1这是我得到的输出。。。
data   # assume you have your data in a var called data

from collections import defaultdict
from calendar import month_abbr

# slightly strange construction here but we want a 2 levels of defaultdict followed by lists
aggregate = defaultdict(lambda:defaultdict(list))

# then the population is super simple - you'll end up with something like
# aggregate[year][month] = [name1, name2]
for person in data['persons']:
    day, month, year = map(int, person['dob'].split('-'))
    aggregate[year][month].append(person['name'])


# I'm sorting in chronological order for printing
for year, months in sorted(aggregate.items()):
    print('{}: {}'.format(year, sum(len(names) for names in months.values())))
    for month, names in sorted(months.items()):
        print('--{}: {}'.format(month_abbr[month], len(names)))

for year, months in sorted(aggregate.items()):
    for month, names in sorted(months.items()):
        print('{} {}: {}'.format(month_abbr[month], year, len(set(names))))
agg_years = defaultdict(lambda:defaultdict(int))   # [year][month] = counter
agg_years_total = defaultdict(int)   # [year] = counter
agg_months_names = defaultdict(set)   # [(year, month)] = set(name1, name2...)

for person in data['persons']:
    day, month, year = map(int, person['dob'].split('-'))

    agg_years[year][month] += 1
    agg_years_total[year] += 1
    agg_months_names[(year, month)].add(person['name'])


for year, months in sorted(agg_years.items()):
    print('{}: {}'.format(year, agg_years_total[year]))
    for month, quant in sorted(months.items()):
        print('--{}: {}'.format(month_abbr[month], quant))

for (year, month), names in sorted(agg_months_names.items()):
    print('{} {}: {}'.format(month_abbr[month], year, len(names)))