AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 77942862
Accepted
Serge de Gosson de Varennes
Serge de Gosson de Varennes
Asked: 2024-02-06 01:27:54 +0800 CST2024-02-06 01:27:54 +0800 CST 2024-02-06 01:27:54 +0800 CST

Função para agregar json

  • 772

Suponha que eu tenha um bucket gcs com arquivos json com a seguinte estrutura:

[
  {
    "Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "Name": "alibaba",
    "storeid": "Y1",
    "storeName": "alibaba1",
    "a": "1/2/3",
    "b": "1.0/1.0/3",
    "c": "0/0/0",
    "d": "0/0/0",
    "e": "1.8/3.4",
    "f": "1/2/3",
    "g": "1/2/3",
  },
  {
    "Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "Name": "alibaba",
    "storeUuid": "Y2",
     "storeName": "alibaba2",
    "a": "1/2/3",
    "b": "1.0/1.0/3",
    "c": "0/0/0",
    "d": "0/0/0",
    "e": "1.7/2.4",
    "f": "1/2/3",
    "g": "1/2/3",
  },
  {
    "Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "Name": "alibaba",
    "storeUuid": "Y3",
     "storeName": "alibaba3",
    "a": "1/2/3",
    "b": "1.0/1.0/3",
    "c": "0/0/0",
    "d": "0/0/0",
    "e": "2.7/4.4",
    "f": "1/2/3",
    "g": "1/2/3",
  },
  {
    "Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "Name": "alibaba",
    "storeUuid": "Y4",
     "storeName": "alibaba4",
    "a": "1/2/3",
    "b": "1.0/1.0/3",
    "c": "0/0/0",
    "d": "0/0/0",
    "e": "3.7/5.4",
    "f": "1/2/3",
    "g": "1/2/3",
  }
]

O que eu quero fazer é agregar os diferentes valores somando a, b,c, d, f,ge calculando a média epara retornar um único jsoncomo

[
{
    "Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "Name": "alibaba",
    "a": "sum over all first instance/sum over all second instances/sum aover all third instance",
    "b": "sum over all first instance/sum over all second instances/sum aover all third instance",
    "c": "sum over all first instance/sum over all second instances/sum aover all third instance",
    "d": "sum over all first instance/sum over all second instances/sum aover all third instance",
    "e": "average over all first instance/average over all second instance",
    "f": "sum over all first instance/sum over all second instances/sum aover all third instance",
    "g": "sum over all first instance/sum over all second instances/sum aover all third instance",
  }
]

Não que algum dos valores em */*/*possa ser NaN e que os dados em epossam ser uma string data unvavailable.

Em criei esta função

def format_large_numbers_optimized(value):
    abs_values = np.abs(value)
    mask = abs_values >= 1e6
    formatted_values = np.where(mask, 
                                np.char.add(np.round(value / 1e6, 2).astype(str), "M"), 
                                np.round(value, 2).astype(str))
    return formatted_values

def process_json_data_optimized(json_list):
    result = {}
    keys = set(json_list[0].keys()) - {'Id', 'Name', 'storeid', 'storeName'}
    for key in keys:
        result[key] = {'values': []}
    for json_data in json_list:
        for key in keys:
            value = json_data.get(key, '0')  
            result[key]['values'].append(value)
    for key in keys:
        all_values_processed = []
        for value in result[key]['values']:
            if isinstance(value, str) and '/' in value:
                processed_values = [float(v) if v != 'data unavailable' else 0 for v in value.split('/')]
            elif isinstance(value, float) or isinstance(value, int):
                processed_values = [value]
            else:
                processed_values = [0.0]  
            all_values_processed.append(processed_values)
        numeric_values = np.array(all_values_processed)
        if numeric_values.ndim == 1:
            numeric_values = numeric_values[:, np.newaxis]
        summed_values = np.sum(numeric_values, axis=0)
        formatted_summed_values = '/'.join(format_large_numbers_optimized(summed_values))
        result[key]['summed'] = formatted_summed_values
    processed_result = {key: data['summed'] for key, data in result.items()}
    processed_result['Id'] = json_list[0]['Id']
    processed_result['Name'] = json_list[0]['Name']
    return processed_result

Mas isso não cria o que eu espero. Estou totalmente perdido. Eu realmente apreciaria qualquer ajuda.

python
  • 2 2 respostas
  • 43 Views

2 respostas

  • Voted
  1. Best Answer
    Bob
    2024-02-06T01:53:41+08:002024-02-06T01:53:41+08:00

    Observe que você está colocando os valores como listas all_values_processed. Supondo que o /caractere seja apenas um separador, e que o que você deseja substituindo all_values_processed.append(processed_values)por all_values_processed += processed_values. Ou melhor ainda, você poderia apenas agregar os valores.

    Por exemplo, você poderia ter uma função para agregar assim

    import math
    def agg_func(value, initial):
      v_count, v_sum = initial
      if isinstance(value, str) and '/' in value:
        for v in value.split('/'):
          if v != 'data unavailable' :
             v = float(v)
             if not math.isnan(v):
               v_sum += v
               v_count += 1
      elif isinstance(value, float) or isinstance(value, int):
        if not math.isnan(value):
          v_sum += value
          v_count += 1
      return v_count, v_sum
    

    Uma função que agrega as chaves fornecidas no json

    def agg_json(v_list, fields):
      state = {k: (0, 0) for k in fields}
      for item in v_list:
        for k in fields:
          if k in item:
            state[k] = agg(item[k], state[k])
      return state
    

    Agora

    state = agg_json(json_list, ['a', 'b', 'c', 'd', 'e', 'f', 'g'])
    

    fornecerá um dicionário com tuplas contendo a contagem e a soma de cada campo. Para obter sua resposta final, você poderia fazer

    result = {k: v[1] / v[0] if k == 'e' else v[1] for k, v in state.items()}
    
    • 1
  2. Timeless
    2024-02-06T03:23:38+08:002024-02-06T03:23:38+08:00

    Já que você marcou os pandas e se eu acertei o OP, aqui está uma solução genérica em potencial:

    IN_SEP = OUT_SEP = "/"
    
    ids = ["Id", "Name"]
    metrics = df.columns.difference(
        [*ids, "storeUuid", "storeName"], sort=False
    )
    aggs = dict.fromkeys(metrics.difference(["e"]), "sum") | {"e": "mean"}
    
    out = (
        df.set_index(ids, append=True)[metrics]
        .stack().str.split(IN_SEP, expand=True)
        .apply(pd.to_numeric,errors="coerce")
        .unstack().stack(0, future_stack=True)
        .groupby(level=list(range(1, len(ids) + 2)))
        .agg(aggs).round(2).groupby(ids).agg(
            lambda s: s.astype(str).replace("nan", "")
             .str.cat(sep=OUT_SEP).strip(OUT_SEP))[metrics]
        .reset_index().to_dict("records")
    )
    

    Saída :

    print(json.dumps(out, indent=4))
    
    [
        {
            "Id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "Name": "alibaba",
            "a": "4.0/8.0/12.0",
            "b": "4.0/4.0/12.0",
            "c": "0.0/0.0/0.0",
            "d": "0.0/0.0/0.0",
            "e": "2.48/3.9",
            "f": "4.0/8.0/12.0",
            "g": "4.0/8.0/12.0"
        }
    ]
    

    Entrada usada:

    # with a fixed typo in the 1st record : "storeUuid" instead of "storeid"
    with open("file.json", "r") as file:
        import json # if json-fmt
        # json_list = json.load(file)
    
        from ast import literal_eval
        json_list = literal_eval(file.read())
    
        import pandas as pd
        df = pd.DataFrame(json_list)
    
    • 1

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve