Ausgabe
Ich habe diesen JSON-String:
{
"2022-09-28T00:45:00.000Z": [
{
"value": 0.216,
"plantId": "27050937",
"man": "pippo"
},
{
"value": 0.224,
"plantId": "30082443",
"man": "pippo"
}
],
"2022-09-28T00:30:00.000Z": [
{
"value": 0.248,
"plantId": "27050937",
"man": "pippo"
},
{
"value": 0.108,
"plantId": "30082443",
"man": "pippo"
}
]
}
Ich möchte die Daten importieren, um eine numpy-Matrix zu erstellen, die als (plantId, time) indiziert ist. Zum Beispiel würde ich eine Matrix wie folgt erhalten:
300082443 0.216 0.108
27050937 0.224 0.248
....
Ich habe es mit Pandas versucht:
a =pd.read_json("./data.json",orient='index')
Aber ich bekomme:
2022-09-28 00:45:00+00:00 {'value': 0.216, 'plantId': '27050937', 'man... {'value': 0.224, 'plantId': '30082443', 'man...
2022-09-28 00:30:00+00:00 {'value': 0.248, 'plantId': '27050937', 'man... {'value': 0.108, 'plantId': '30082443', 'man...
Lösung
Die Antwort von @jezrael ist viel kürzer und effizienter.
Kombination der beiden Antworten:
df = pd.DataFrame([{**{'date': k}, **x} for k, v in a.items() for x in v]) #jezrael's answer
df2=df.groupby('plantId')['value'].agg(list).reset_index()
df2[['value_1','value_2']] = pd.DataFrame(df2.value.tolist(), index= df2.index)
df2
'''
plantId value value_1 value_2
0 27050937 [0.216, 0.248] 0.216 0.248
1 30082443 [0.224, 0.108] 0.224 0.108
'''
Details (lange Lösung):
a={
"2022-09-28T00:45:00.000Z": [
{
"value": 0.216,
"plantId": "27050937",
"man": "pippo"
},
{
"value": 0.224,
"plantId": "30082443",
"man": "pippo"
}
],
"2022-09-28T00:30:00.000Z": [
{
"value": 0.248,
"plantId": "27050937",
"man": "pippo"
},
{
"value": 0.108,
"plantId": "30082443",
"man": "pippo"
}
]
}
df=pd.DataFrame(a)
2022-09-28T00:45:00.000Z 2022-09-28T00:30:00.000Z
0 {'value': 0.216, 'plantId': '27050937', 'man': 'pippo'} {'value': 0.248, 'plantId': '27050937', 'man': 'pippo'}
1 {'value': 0.224, 'plantId': '30082443', 'man': 'pippo'} {'value': 0.108, 'plantId': '30082443', 'man': 'pippo'}
Mit zunehmender Datenmenge nimmt auch die Anzahl der Spalten zu. Jetzt müssen wir diese Spalten in Zeilen umwandeln.
df = df.T.reset_index() # T = transpose()
Wir haben die Transpose- Funktion verwendet, um Spalten in Zeilen umzuwandeln. letzte Version:
index 0 1
0 2022-09-28T00:45:00.000Z {'value': 0.216, 'plantId': '27050937', 'man': 'pippo'} {'value': 0.224, 'plantId': '30082443', 'man': 'pippo'}
1 2022-09-28T00:30:00.000Z {'value': 0.248, 'plantId': '27050937', 'man': 'pippo'} {'value': 0.108, 'plantId': '30082443', 'man': 'pippo'}
Lassen Sie uns nun die Wörterbuchobjekte (Spalten 0 und 1) in den Zeilen in neue Spalten zerlegen. Wir werden dafür die Funktion json_normalize verwenden.
first= pd.json_normalize(df.pop(0))
df=df.join(first)
second=pd.json_normalize(df.pop(1))
df = pd.concat([df,second])
print(df)
'''
index value plantId man
0 2022-09-28T00:45:00.000Z 0.216 27050937 pippo
1 2022-09-28T00:30:00.000Z 0.248 27050937 pippo
0 NaN 0.224 30082443 pippo
1 NaN 0.108 30082443 pippo
'''
#if you want to fill NaNs use:
df = df.fillna({'index':df[['index']][df['index'].notnull()].squeeze()})
#fill nans with same index number.
'''
index value plantId man
0 2022-09-28T00:45:00.000Z 0.216 27050937 pippo
1 2022-09-28T00:30:00.000Z 0.248 27050937 pippo
0 2022-09-28T00:45:00.000Z 0.224 30082443 pippo
1 2022-09-28T00:30:00.000Z 0.108 30082443 pippo
'''
json_normalize gibt nur die verarbeiteten Spaltenwerte zurück. Aber wir brauchen auch andere Spalten, also verwenden wir die Join- Funktion. Dann sollten wir die gleiche Operation in der Spalte mit dem Namen 1 durchführen. Aber hier verwende ich concat anstelle von join, weil die Spaltennamen gleich sind und ich möchte, dass die Daten untereinander eingefügt werden (als Zeilen, nicht als Spalten). Gruppieren Sie schließlich nach plant_id und fügen Sie die Werte zur Liste hinzu. Teilen Sie dann die Listenelemente in neue Spalten auf.
df2=df.groupby('plantId')['value'].agg(list).reset_index()
df2[['value_1','value_2']] = pd.DataFrame(df2.value.tolist(), index= df2.index)
print(df2)
'''
plantId value value_1 value_2
0 27050937 [0.216, 0.248] 0.216 0.248
1 30082443 [0.224, 0.108] 0.224 0.108
'''
Beantwortet von – Clegane
Antwort geprüft von – Marie Seifert (FixError Admin)