#json #python-3.x #pandas #database #csv
#json #python-3.x #панды #База данных #csv
Вопрос:
Я конвертирую вложенный файл json, содержащий более 100 записей, в файл flattend csv. Пример файла json показан ниже:
sampleJson = {
'record1':
{
'text':[ ['A', 'fried', 'is', 'a', 'nice', 'companion', '.'],
['The', 'birds', 'are', 'flying', '.']],
'values':[ [0, 1, 0, 0],
[1, 1, 0, 1]],
'pairs':[ [0, 2],
[2, 1]]
},
'record2':
{
'text':[ ['We', 'can', 'work', 'hard', 'together', '.'],
['Let', 'the', 'things', 'happen', '.'],
['There', 'is', 'always', 'a', 'way', 'out', '.']],
'values':[ [0, 1, 0, 0],
[0, 1, 1, 1],
[1, 1, 0, 1]],
'pairs':[ [0, 2],
[3, 4],
[2, 1]]
},
..... 100 records
}
Структура csv, которую я хочу получить из этого вложенного json,:
record1, A friend is a nice companion., 0, 1, 0, 0, [0, 2]
, The bids are flying., 1, 1, 0, 1, [2, 1]
record2, We can work hard together., 0, 1, 0, 0, [0, 2]
, Let the things happen., 0, 1, 1, 1, [4, 3]
, There is always a way out., 1, 1, 0, 1, [2, 1]
record3,
....... upto 100 records
Я использовал следующий код для выравнивания вложенного файла:
def flatten_json(y):
out = {}
def flatten(x, name=''):
if type(x) is dict:
for a in x:
flatten(x[a], name a '_')
elif type(x) is list:
i = 0
for a in x:
flatten(a, name str(i) '_')
i = 1
else:
out[name[:-1]] = x
flatten(y)
return out
flatIt = flatten_json(sampleJson)
df= pd.json_normalize(flatIt)
df.to_csv('outPutFile.csv', encoding='utf-8')
print(df)
Я получаю длинный список столбцов со структурой типа record1.text, record1.values, record1.pairs, record2.text и так далее с одной строкой, а также каждое слово предложений в тексте находится в отдельном столбце.
Я буду признателен за некоторую помощь. Спасибо..
Ответ №1:
Вы можете использовать этот пример для анализа Json в dataframe:
import pandas as pd
sampleJson = {
'record1':
{
'text':[ ['A', 'fried', 'is', 'a', 'nice', 'companion', '.'],
['The', 'birds', 'are', 'flying', '.']],
'values':[ [0, 1, 0, 0],
[1, 1, 0, 1]],
'pairs':[ [0, 2],
[2, 1]]
},
'record2':
{
'text':[ ['We', 'can', 'work', 'hard', 'together', '.'],
['Let', 'the', 'things', 'happen', '.'],
['There', 'is', 'always', 'a', 'way', 'out', '.']],
'values':[ [0, 1, 0, 0],
[0, 1, 1, 1],
[1, 1, 0, 1]],
'pairs':[ [0, 2],
[3, 4],
[2, 1]]
},
}
all_data = []
for k, v in sampleJson.items():
texts, values, pairs = v['text'], v['values'], v['pairs']
for t, val, p in zip(texts, values, pairs):
all_data.append({
'record': k,
'text': ' '.join(t),
'pairs': p,
**{'val_{}'.format(i): val_ for i, val_ in enumerate(val, 1)}
})
df = pd.DataFrame(all_data)
print(df)
Печатает этот фрейм данных:
record text pairs val_1 val_2 val_3 val_4
0 record1 A fried is a nice companion . [0, 2] 0 1 0 0
1 record1 The birds are flying . [2, 1] 1 1 0 1
2 record2 We can work hard together . [0, 2] 0 1 0 0
3 record2 Let the things happen . [3, 4] 0 1 1 1
4 record2 There is always a way out . [2, 1] 1 1 0 1
Комментарии:
1. Привет, Андрей, большое спасибо за помощь. Я действительно ценю это, поскольку я боролся с этим в течение недели. У меня просто есть несколько вопросов, чтобы лучше понять код, поскольку это шанс учиться (я очень плохо разбираюсь во вложенных структурах). Почему вы использовали zip во втором цикле? и если вместо текста, значений и столбцов пар есть разные числа. Например, в каждой записи на 2-м уровне у меня разные числа, скажем, 11, 23, 14 в первой записи и 12, 34 12 во второй записи и так далее с тем же содержимым. Было бы здорово, если бы вы могли немного помочь, если у вас есть время, в противном случае большое спасибо.
2. @codeDB я использовал
zip()
для «связывания» значений из'text'
'values'
и'pairs'
списков вместе. Каждый элемент из этих списков принадлежит одной строке.3. Большое спасибо. Мне удалось решить второй вопрос, который я задал, о наличии чисел вместо текста, значений и пар.