Как создать DataFrame из данных JSON - диктовки, списки и массивы в массиве - PullRequest
1 голос
/ 04 октября 2019

Я не могу получить данные, но только заголовки из данных json

Попытался использовать json_normalize, который создает DataFrame из данных json, но когда я пытаюсь зациклить и добавить данные, результатчто я получаю только заголовки.

import pandas as pd
import json
import requests
from pandas.io.json import json_normalize
import numpy as np

# importing json data

def get_json(file_path):
    r = requests.get('https://www.atg.se/services/racinginfo/v1/api/games/V75_2019-09-29_5_6')
    jsonResponse = r.json()
    with open(file_path, 'w', encoding='utf-8') as outfile:
        json.dump(jsonResponse, outfile, ensure_ascii=False, indent=None)

# Run the function and choose where to save the json file
get_json('../trav.json')

# Open the json file and print a list of the keys
with open('../trav.json', 'r') as json_data:
    d = json.load(json_data)

    print(list(d.keys()))

[Out]:
['@type', 'id', 'status', 'pools', 'races', 'currentVersion']

Чтобы получить все данные для стартов в одной гонке, я могу использовать функцию json_normalize

race_1_starts = json_normalize(d['races'][0]['starts'])
race_1_starts_df = race_1_starts.drop('videos', axis=1)
print(race_1_starts_df)

[Out]:
    distance  driver.birth  ... result.prizeMoney  result.startNumber
0       1640          1984  ...             62500                   1
1       1640          1976  ...             11000                   2
2       1640          1968  ...               500                   3
3       1640          1953  ...            250000                   4
4       1640          1968  ...               500                   5
5       1640          1962  ...             18500                   6
6       1640          1961  ...              7000                   7
7       1640          1989  ...             31500                   8
8       1640          1960  ...               500                   9
9       1640          1954  ...               500                  10
10      1640          1977  ...            125000                  11
11      1640          1977  ...               500                  12

Выше мы получаем DataFrame с данными обо всех стартах. из одной расы. Однако, когда я пытаюсь перебрать все расы в диапазоне, чтобы получить данные обо всех стартах для всех рас, я получаю только заголовки от каждой расы, а не данные о стартах для каждой расы:


all_starts = []

for t in range(len(d['races'])):

    all_starts.append([t+1, json_normalize(d['races'][t]['starts'])])

all_starts_df = pd.DataFrame(all_starts, columns = ['race', 'starts'])
print(all_starts_df)

[Out]:
   race                                             starts
0     1      distance  ...                             ...
1     2      distance  ...                             ...
2     3      distance  ...                             ...
3     4      distance  ...                             ...
4     5      distance  ...                             ...
5     6      distance  ...                             ...
6     7      distance  ...                             ...

В выводе я хочу DataFrame, который представляет собой объединение данных на всех запусках со всех рас. Обратите внимание, что количество столбцов может различаться в зависимости от расы, но я ожидаю, что если в одной гонке 21 столбец, а в другой - 20 столбцов, то файл all_starts_df должен содержать все столбцы, но в случае, если в гонке нет данных для одного столбца,должен сказать «NaN».

Ожидаемый результат:

[Out]:
race  distance  driver.birth  ... result.column_20     result.column_22
1       1640          1984  ...             12500                   1
1       1640          1976  ...             11000                   2
2       2140          1968  ...               NaN                   1
2       2140          1953  ...               NaN                   2
3       3360          1968  ...              1500                 NaN
3       3360          1953  ...            250000                 NaN

1 Ответ

0 голосов
/ 04 октября 2019

Если вам нужны все столбцы, вы можете попробовать это .. (Я нахожу намного больше, чем 20 столбцов, поэтому я могу ошибиться.)

all_starts = []
headers = []
for idx, race in enumerate(d['races']):
    df = json_normalize(race['starts'])
    df['race'] = idx
    all_starts.append(df.drop('videos', axis=1))
    headers.append(set(df.columns))

# Create set of all columns for all races
columns = set.union(*headers)

# If columns are missing from one dataframe add it (as np.nan)
for df in all_starts:
    for c in columns - set(df.columns):
        df[c] = np.nan

# Concatenate all dataframes for each race to make one dataframe
df_all_starts = pd.concat(all_starts, axis=0, sort=True)

В качестве альтернативы, если вы знаете имена столбцовВы хотите сохранить, попробуйте это

columns = ['race', 'distance', 'driver.birth', 'result.prizeMoney']
all_starts = []

for idx, race in enumerate(d['races']):
    df = json_normalize(race['starts'])
    df['race'] = idx
    all_starts.append(df[columns])

# Concatenate all dataframes for each race to make one dataframe
df_all_starts = pd.concat(all_starts, axis=0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...