Разбор строки JSON, загруженной из CSV с использованием Pandas
Коллеги, мучаюсь с такой задачей: есть csv файл такого типа:
1;{'BT3': ['1.667', 13, '1:2 02:27', 7.61], 'PAC': ['1.4', 15, '1:2 (1:2) 22:00', None], 'BCT': ['1.49', 0, '1:2 (1:2) 00:02', 7.93], 'WLN': ['1.44', 7, '1:2 (1:2)', 11.46], 'LIG': ['1.37', 3, '1:2 (1:2)', 7.96]};a44ab8cf2f9334b2d1;TEAM_TOTALS;P2__TOTALS__OVER(2.5)
2;{'BT3': ['1.667', 17, '1:2 02:32', 7.61], 'PAC': ['1.4', 19, '1:2 (1:2) 22:00', None], 'BCT': ['1.49', 4, '1:2 (1:2) 00:06', 7.93], 'WLN': ['1.44', 11, '1:2 (1:2)', 11.46], 'LIG': ['1.37', 7, '1:2 (1:2)', 7.96]};a44ab8cf2f9334b2d1;TEAM_TOTALS;P2__TOTALS__OVER(2.5)
3;{'BT3': ['1.667', 20, '1:2 02:35', 7.61], 'PAC': ['1.4', 22, '1:2 (1:2) 22:00', None], 'BCT': ['1.49', 7, '1:2 (1:2) 00:02', 7.93], 'WLN': ['1.44', 14, '1:2 (1:2)', 11.46], 'LIG': ['1.37', 10, '1:2 (1:2)', 7.96]};a44ab8cf2f9334b2d1;TEAM_TOTALS;P2__TOTALS__OVER(2.5)
Никак не получается корректно разбить на столбцы с применением pandas. Подскажите, пожалуйста. Попытался так:
df = pd.read_csv(r'file.csv', converters={'json_column_name': eval})
очень некорректно делает разбивку по столбцам и еще первую строку выносит в заголовки.
Ответы (1 шт):
Как вам уже подсказали, во время чтения файла нужно указать разделитель ;. Если не хотите, чтобы элементы первой строки становились названием столбцов, то это тоже укажите (header=None):
In [60]: import pandas as pd
In [61]: import ast
In [62]: df = pd.read_csv('json_column.csv', sep=';', header=None, converters={1: ast.literal_eval})
In [63]: df
Out[63]:
0 1 2 \
0 1 {'BT3': ['1.667', 13, '1:2 02:27', 7.61], 'PAC... a44ab8cf2f9334b2d1
1 2 {'BT3': ['1.667', 17, '1:2 02:32', 7.61], 'PAC... a44ab8cf2f9334b2d1
2 3 {'BT3': ['1.667', 20, '1:2 02:35', 7.61], 'PAC... a44ab8cf2f9334b2d1
3 4
0 TEAM_TOTALS P2__TOTALS__OVER(2.5)
1 TEAM_TOTALS P2__TOTALS__OVER(2.5)
2 TEAM_TOTALS P2__TOTALS__OVER(2.5)
На данном этапе, элементы колонки 1 являются словарями. Далее нужно распарсить их. Для этого можно воспользоваться pandas.json_normalize():
In [64]: pd.json_normalize(df[1])
Out[64]:
BT3 PAC \
0 [1.667, 13, 1:2 02:27, 7.61] [1.4, 15, 1:2 (1:2) 22:00, None]
1 [1.667, 17, 1:2 02:32, 7.61] [1.4, 19, 1:2 (1:2) 22:00, None]
2 [1.667, 20, 1:2 02:35, 7.61] [1.4, 22, 1:2 (1:2) 22:00, None]
BCT WLN \
0 [1.49, 0, 1:2 (1:2) 00:02, 7.93] [1.44, 7, 1:2 (1:2), 11.46]
1 [1.49, 4, 1:2 (1:2) 00:06, 7.93] [1.44, 11, 1:2 (1:2), 11.46]
2 [1.49, 7, 1:2 (1:2) 00:02, 7.93] [1.44, 14, 1:2 (1:2), 11.46]
LIG
0 [1.37, 3, 1:2 (1:2), 7.96]
1 [1.37, 7, 1:2 (1:2), 7.96]
2 [1.37, 10, 1:2 (1:2), 7.96]
Объединим эти столбцы с основным датафреймом:
In [65]: df.drop(1, axis='columns').join(pd.json_normalize(df[1]))
Out[65]:
0 2 3 4 \
0 1 a44ab8cf2f9334b2d1 TEAM_TOTALS P2__TOTALS__OVER(2.5)
1 2 a44ab8cf2f9334b2d1 TEAM_TOTALS P2__TOTALS__OVER(2.5)
2 3 a44ab8cf2f9334b2d1 TEAM_TOTALS P2__TOTALS__OVER(2.5)
BT3 PAC \
0 [1.667, 13, 1:2 02:27, 7.61] [1.4, 15, 1:2 (1:2) 22:00, None]
1 [1.667, 17, 1:2 02:32, 7.61] [1.4, 19, 1:2 (1:2) 22:00, None]
2 [1.667, 20, 1:2 02:35, 7.61] [1.4, 22, 1:2 (1:2) 22:00, None]
BCT WLN \
0 [1.49, 0, 1:2 (1:2) 00:02, 7.93] [1.44, 7, 1:2 (1:2), 11.46]
1 [1.49, 4, 1:2 (1:2) 00:06, 7.93] [1.44, 11, 1:2 (1:2), 11.46]
2 [1.49, 7, 1:2 (1:2) 00:02, 7.93] [1.44, 14, 1:2 (1:2), 11.46]
LIG
0 [1.37, 3, 1:2 (1:2), 7.96]
1 [1.37, 7, 1:2 (1:2), 7.96]
2 [1.37, 10, 1:2 (1:2), 7.96]
Элементы новых столбцов - списки. Их тоже можно как-то обработать, но вы не уточнили какой вид вам нужен.