【问题标题】:Large amount of data and for loop optimization大量数据和for循环优化
【发布时间】:2021-08-15 09:02:16
【问题描述】:

我有一个大的 JSON 对象。一部分是:

data = [
{  
   'make': 'dacia',
   'model': 'x',
   'version': 'A',
   'typ': 'sedan',
   'infos': [
            {'id': 1, 'name': 'steering wheel problems'}, 
            {'id': 32, 'name': 'ABS errors'}
   ]
},
{  
   'make': 'nissan',
   'model': 'z',
   'version': 'B',
   'typ': 'coupe',
   'infos': [
         {'id': 3,'name': 'throttle problems'}, 
         {'id': 56, 'name': 'broken handbreak'}, 
         {'id': 11, ;'name': 'missing seatbelts'}
   ]
}
]

我创建了一个我感兴趣且可能出现在我的 JSON 中的信息列表:

make = ['ford', 'fiat', 'nissan', 'suzuki', 'dacia']
model = ['x', 'y', 'z']
version = ['A', 'B', 'C']
typ = ['sedan', 'coupe', 'van', 'kombi']

现在我需要遍历整个 JSON data 并计算某些信息组合出现的次数,所以我创建了一个代码:

tab = []
s = 0
for ma in make:
   for mo in model:
      for ve in version:
        for ty in typ:
           s = sum([1 for k in data if k['make] == ma and k['model] == mo and k['version'] == ve and k['typ'] == ty)
            if s != 0:
                total.append({'make': i, 'model': j, 'version': i, 'typ': j, 'sum': s})

我面临的问题是我知道这不是最佳方式。有什么方法可以加快和改进这段代码?

【问题讨论】:

标签: python json for-loop optimization


【解决方案1】:

您可以将键用作元组(4 个元组)并实现自己的计数器

from collections import defaultdict

res = defaultdict(int)

for i in data:
    res[i['make'],i['model'], i['version'], i['typ']] += 1

然后,您可以从 res 过滤您不需要的组合,您可以使用 if 检查 4 元组是否来自您需要过滤的组合集。所以让它成为线性的。

编辑,也可以使用collections.Counter

from collections import Counter
res = Counter((i['make'],i['model'], i['version'], i['typ']) for i in data)

如果您有一个名为combinations 的组合集,则添加过滤器可能类似于。 Python 3.8+

combinations = {your_combination_set_that_has_tuples}
res = Counter(key for i in data if (key := (i['make'],i['model'], i['version'], i['typ'])) in combinations)

【讨论】:

    【解决方案2】:

    使用

    • Pandas 中的 Groupby 生成组合组
    • 计数函数计算每组的大小
    • 避免 Python for 循环,这对于 JSON 结构中的大型列表来说很慢

    正确的数据(发布有错误,即虚假的';')

    data = [
    {  
       'make': 'dacia',
       'model': 'x',
       'version': 'A',
       'typ': 'sedan',
       'infos': [
                {'id': 1, 'name': 'steering wheel problems'}, 
                {'id': 32, 'name': 'ABS errors'}
       ]
    },
    {  
       'make': 'nissan',
       'model': 'z',
       'version': 'B',
       'typ': 'coupe',
       'infos': [
             {'id': 3,'name': 'throttle problems'}, 
             {'id': 56, 'name': 'broken handbreak'}, 
             {'id': 11, 'name': 'missing seatbelts'}
       ]
    }
    ]
    

    计数组合

    import pandas as pd
    
    # JSON to Pandas DataFrame
    df = pd.json_normalize(data)
    
    # Groupby desired properties and
    # Count size of each group
    result = df.groupby(['make', 'model', 'version', 'typ']).count()
    print(result)
    
    # Output (shows combinations of make, model, version, type and count)
                                      infos
    make    model   version typ 
    dacia   x       A       sedan         1
    nissan  z       B       coupe         1
     
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多