如何将 JSON 文件中的值提取到数据框行中的单独列中

How to extract values in a JSON file into separate columns in a dataframe row

data = json.load(open("C:/Users/<username>/Downloads/one-day-run-record.json","rb"))

df = pd.json_normalize(data)[["summaries", "tags.com.nike.weather", "tags.com.nike.name", "start_epoch_ms", "end_epoch_ms", "metrics"]]
df

我的主要目标是提取 metrics 列中的值。要了解该列的结构,您可以使用下面的行

df.metrics[0]

在下面的代码中,您可以看到按类型分隔的指标。我想要存储在 values 中的所有值,类型为 stepsspeedpace

prov = pd.json_normalize(df.metrics[0])
prov

例如:在类型 steps 中你有这个(你可以在 df.metrics[0] 中签入):

{'type': 'steps',
  'unit': 'STEP',
  'source': 'com.nike.running.android.fullpower',
  'appId': 'com.nike.sport.running.droid',
  'values': [{'start_epoch_ms': 1605042906780,
    'end_epoch_ms': 1605042907751,
    'value': 13},

   {'start_epoch_ms': 1605042907780,
    'end_epoch_ms': 1605042911754,
    'value': 11},

   {'start_epoch_ms': 1605042911772,
    'end_epoch_ms': 1605042915741,
    'value': 6},

   {'start_epoch_ms': 1605042915741,
    'end_epoch_ms': 1605042918713,
    'value': 13},

   {'start_epoch_ms': 1605042918713,
    'end_epoch_ms': 1605042920746,
    'value': 5},
    
...}]}

我想要一行包含值 [13, 11, 6, 13, 5, ...],每个值都在不同的数据框列中。

是不是太难做了?我怎么能那样做?我尝试了多种方法,但我对 .json 个文件

完全陌生
  • 'metrics' 中的 'values' 列是 dictslist
    • 为了提取 'value'lists 需要用 .explode() 扩展,以便每个 dict 都在单独的行上。
    • 'values'现在是dicts的一列,需要转换成dataframe
import pandas as pd
import json
from pathlib import Path

# path to JSON file
p = Path('test.json')

# load the JSON file into a python object
with p.open('r', encoding='utf-8') as f:
    data = json.loads(f.read())

# convert the metrics key into a dataframe
df = pd.json_normalize(data, 'metrics', ['id', 'start_epoch_ms', 'end_epoch_ms'])

# explode the values column
dfe = df.explode('values').reset_index(drop=True)

# convert the column of dicts into a dataframe and join it back to dfe
dfj = dfe.join(pd.DataFrame(dfe.pop('values').values.tolist()), rsuffix='_values')

# groupby the type column and then aggregate the value column into a list
dfg = dfj.groupby('type')['value'].agg(list).reset_index(name='values_list')

# merge the desired list of values back to df
df = df.merge(dfg, on='type').drop(columns=['values'])

# select the final types
desired = df.loc[df['type'].isin(['steps', 'speed', 'pace'])]

# to separate each value in the list to a separate column
final = pd.DataFrame(desired.values_list.to_list(), index=desired.type.to_list())

# display(final.iloc[:, :5])
               0          1         2          3         4        ...
steps  13.000000  11.000000  6.000000  13.000000  5.000000        ...
speed   0.000000   0.000000  0.000000   0.000000  0.000000        ...
pace    8.651985   8.651985  6.542049   6.542049  6.173452        ...

# aggregate calculations
final.agg({'steps': 'sum', 'speed': 'mean', 'pace': 'mean'}, axis=1)

steps    2676.000000
speed       9.657251
pace        5.544723
dtype: float64

数据框截图

  • dataframe 中的数据太多到 post 文本示例,所以这里有一些屏幕截图以提供分解的想法

初始df

  • 共 9 行

dfe

  • 展开列共创建 699 行

dfj

  • 从列创建一个数据框并将其连接到 dfe

dfg

  • 创建所需值的列表

决赛df

  • values_list 是所需的值

desired

  • 只选择了想要的'types'