0
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我想要为类型存储的所有值stepsspeed并且pace

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},
    
...}]}

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

做起来是不是太难了?我怎么能那样做?我尝试了多种方法,但我对.json文件完全陌生

4

1 回答 1

0
  • 中的'values''metrics'listdicts
    • 为了提取'value'lists需要扩展 ,.explode()以便每个dict都在单独的行上。
    • 'values'现在是 的一列dicts,需要将其转换为数据框。
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

数据框截图

  • 数据框中有很多数据可以发布文本示例,所以这里有一些屏幕截图可以让您了解细分

最初的df

  • 共 9 行 在此处输入图像描述

dfe

  • 分解列创建总共 699 行 在此处输入图像描述

dfj

  • 从该列创建一个数据框并将其加入dfe 在此处输入图像描述

dfg

  • 创建所需值的列表 在此处输入图像描述

最后df

  • values_list是期望的值 在此处输入图像描述

desired

  • 只选择了想要的'types' 在此处输入图像描述
于 2021-01-25T23:57:50.997 回答