#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
Я пытаюсь создать фрейм данных из сложного словаря здесь, но я не могу решить значения для последнего столбца, если бы вы могли, пожалуйста, направить меня, это было бы здорово!
код —
import pandas as pd
from pandas.io.json import json_normalize
stream= {
"Outerclass": {
"Main_ID": "1",
"SetID": "1041",
"Version": 2,
"nestedData": {
"time": ["5000", "6000", "7000"],
"values": [{"intValue":1,"value":"intValue"}, {"floatValue":2.5,"value":"floatValue"}, {"stringValue":"abc","value":"stringValue"}]
}
} }
s = json_normalize(stream['Outerclass'])
s = s.join(pd.concat([s.pop(x).explode() for x in ['nestedData.time','nestedData.values']],axis=1))
print(s)
Желаемый результат-
Main_ID SetID Version nestedData.time nestedData.values
1 1041 2 5000 1
1 1041 2 6000 2.5
1 1041 2 7000 abc
Фактический результат —
Main_ID SetID Version nestedData.time nestedData.values
1 1041 2 5000 {'intValue': 1, 'value': 'intValue'}
1 1041 2 6000 {'floatValue': 2.5, 'value': 'floatValue'}
1 1041 2 7000 {'stringValue': 'abc', 'value': 'stringValue'}
Комментарии:
1. Первый ключ
nestedData.values
отличается для каждой строки (например'intValue'
,floatValue
,stringValue
), поэтому, даже если вы еще раз нормализуете этот json, все они будут отдельными столбцами. Вы хотите по существу игнорировать имя этого ключа и получать связанное значение независимо от того, является ли оноintValue
,floatValue
, и т. Д.?2. да, мне нужно игнорировать подтекст первого ключа и хотеть только связанное значение
Ответ №1:
Поскольку вы хотите извлечь некоторые из этих полей на основе пользовательской логики (не обязательно классической нормализации json), что требует игнорирования подтекста первого ключа и, по сути, получения любого значения, связанного с ключом, которого нет value
, я бы предложил следующее:
# Almost same as before
s = pd.json_normalize(stream['Outerclass']) #pandas.io.json.json_normalize is actually deprecated
s = s.join(pd.concat(
[s.pop(x).explode() for x in ['nestedData.time','nestedData.values']], axis=1)
).reset_index(drop=True)
def get_value(d):
""" Extract value from any key that is not 'value' """
k = [k for k in d.keys() if k != 'value'][0]
return d.get(k)
s["Values"] = s["nestedData.values"].apply(get_value) # Or you can just replace it
s
Результирующий фрейм данных будет выглядеть следующим образом:
Main_ID SetID Version nestedData.time nestedData.values
0 1 1041 2 5000 1
1 1 1041 2 6000 2.5
2 1 1041 2 7000 abc
Кроме того, просто чтобы отметить альтернативу, используя только нормализацию json:
pd.json_normalize(s["nestedData.values"])
в результате будет получена таблица с каждым возможным ключом в виде столбца, как ожидалось (но не так, как хотелось бы):
intValue value floatValue stringValue
0 1.0 intValue NaN NaN
1 NaN floatValue 2.5 NaN
2 NaN stringValue NaN abc