Criação de Pandas trama de dados a partir SmartSheet API (aninhados, desajeitado, JSON)

votos
0

Eu estou tentando se conectar a SmartSheet API do meu escritório via Python para criar alguns painéis de monitoramento de desempenho que utilizam fora de dados de SmartSheet. Tudo que eu quero fazer é criar uma trama de dados simples, onde campos refletir columnId e valores de célula refletir a chave displayValue no dicionário Smartsheet. Eu estou fazendo isso usando um requests.get API padrão em vez de documentação da API do SmartSheet porque eu encontrei o último menos fácil de trabalhar.

Aqui estão as duas maneiras que eu abordou o problema:

ENTRADA:

from pandas.io.json import json_normalize
dbopj = dbop.json()
dfj_rows = json_normalize(data=dbopj['rows'], record_path='cells', meta=['id', 'rowNumber'])
dfj_rows

RESULTADO:

Trama de dados com columnId, valor disdlayValue, id, e RowNumber como os seus próprios campos.

Se eu pudesse descobrir como transpor esses dados no caminho certo Eu provavelmente poderia fazê-lo funcionar, mas que parece incrivelmente complicado.

ENTRADA:

dbopj = dbop.json()
cellist = []
def get_cells():
    dbrows = dbopj['rows']
    for db_cells in dbrows:
        dbcells = db_cells['cells']
        cellist.append(dbcells)
get_cells()
pd.DataFrame(cellist)

RESULTADO:

Isso retorna uma trama de dados com o número correto de colunas e linhas, mas cada célula é preenchida com um dicionário que se parece

{'columnId': 1500325145274244, 'value': 731.0, 'displayValue': '731'}

Se houvesse uma maneira de remover tudo, exceto o valor correspondente à chave displayValue em cada célula, isso provavelmente resolver o meu problema. Novamente, porém, parece estranhamente complicado.

Eu sou bastante novo para Python e trabalhar com a API do, portanto, pode haver uma maneira simples de resolver o problema que eu estou com vista. Ou, se você tiver alguma sugestão para aproximar as soluções possíveis que descrevi acima eu sou todo ouvidos. Obrigado pela ajuda!

Publicado 13/02/2020 em 21:52
fonte usuário
Em outras línguas...                            


1 respostas

votos
0

Você deve fazer uso do columnscampo:

colnames = {x['id']: x['title'] for x in samplej['columns']}
columns = [x['title'] for x in samplej['columns']]
cellist = [{colnames[scells['columnId']]: scells['displayValue']
            for scells in s_cells['cells']} for s_cells in samplej['rows']]
celldf = pd.DataFrame(cellist, columns=columns)

Isto dá como esperado:

  Number Letter Name
0      1      A  Joe
1      2      B  Jim
2      3      C  Jon

Se algumas células podem conter apenas uma columnId mas nenhum campo displayValue, scells['displayValue']deve ser substituído no código acima com scells.get('displayValue', defaultValue), onde defaultValuepode haver nenhum, np.nanou qualquer outro padrão relevante.

Respondeu 14/02/2020 em 15:02
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more