如何将 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
中的所有值,类型为 steps
、speed
和 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},
...}]}
我想要一行包含值 [13, 11, 6, 13, 5, ...]
,每个值都在不同的数据框列中。
是不是太难做了?我怎么能那样做?我尝试了多种方法,但我对 .json
个文件
完全陌生
'metrics'
中的 'values'
列是 dicts
的 list
- 为了提取
'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'
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
中的所有值,类型为 steps
、speed
和 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},
...}]}
我想要一行包含值 [13, 11, 6, 13, 5, ...]
,每个值都在不同的数据框列中。
是不是太难做了?我怎么能那样做?我尝试了多种方法,但我对 .json
个文件
'metrics'
中的'values'
列是dicts
的list
- 为了提取
'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'