У меня есть данные, сохраненные в базе данных postgreSQL. Я запрашиваю эти данные с помощью Python2.7 и превращаю их в Pandas DataFrame. Однако последний столбец этого информационного кадра содержит словарь (или список?) Значений внутри него. DataFrame выглядит следующим образом:
[1] df
Station ID Pollutants
8809 {"a": "46", "b": "3", "c": "12"}
8810 {"a": "36", "b": "5", "c": "8"}
8811 {"b": "2", "c": "7"}
8812 {"c": "11"}
8813 {"a": "82", "c": "15"}
Мне нужно разделить этот столбец на отдельные столбцы, чтобы DataFrame выглядел следующим образом:
[2] df2
Station ID a b c
8809 46 3 12
8810 36 5 8
8811 NaN 2 7
8812 NaN NaN 11
8813 82 NaN 15
Основная проблема, с которой я сталкиваюсь, заключается в том, что списки имеют разную длину. Но все списки содержат только до 3 одинаковых значений: a, b и c. И они всегда появляются в одном и том же порядке (первое, второе, третье).
Следующий код используется для работы и возврата именно то, что я хотел (df2).
[3] df
[4] objs = [df, pandas.DataFrame(df['Pollutant Levels'].tolist()).iloc[:, :3]]
[5] df2 = pandas.concat(objs, axis=1).drop('Pollutant Levels', axis=1)
[6] print(df2)
Я запускал этот код только на прошлой неделе, и он работал нормально. Но теперь мой код не работает, и я получаю эту ошибку из строки [4]:
IndexError: out-of-bounds on slice (end)
Я не внес никаких изменений в код, но теперь получаю ошибку. Я чувствую, что это из-за того, что мой метод не является надежным или правильным.
Любые предложения или рекомендации о том, как разбить этот столбец списков на отдельные столбцы, будут очень признательны!
РЕДАКТИРОВАТЬ: Я думаю, что методы .tolist () и .apply не работают на моем коде, потому что это одна строка Unicode, то есть:
#My data format
u{'a': '1', 'b': '2', 'c': '3'}
#and not
{u'a': '1', u'b': '2', u'c': '3'}
Данные импортируются из базы данных postgreSQL в этом формате. Любая помощь или идеи по этому вопросу? Есть ли способ конвертировать Unicode?
источник
iloc
iloc[:, :3]
предполагается, что будет 3 элемента, и, возможно, более свежие срезы данных имеют только 1 или 2 (например, такихb
как вindex 8813
)?Ответы:
Чтобы преобразовать строку в настоящий dict, вы можете сделать
df['Pollutant Levels'].map(eval)
. Впоследствии приведенное ниже решение можно использовать для преобразования словаря в разные столбцы.Используя небольшой пример, вы можете использовать
.apply(pd.Series)
:Чтобы объединить его с остальной частью фрейма данных, вы можете
concat
использовать другие столбцы с указанным выше результатом:Используя ваш код, это также работает, если я опущу
iloc
часть:источник
pd.DataFrame(df[col].tolist())
давно, ни разу не задумывалсяapply(pd.Series)
. Очень хорошо.DataFrame(df['col'].tolist())
подход намного быстрее, чем подход apply!df[col].map(eval)
прежде чем преобразовывать ее в DataFrameЯ знаю, что вопрос довольно старый, но я пришел сюда в поисках ответов. На самом деле есть лучший (и более быстрый) способ сделать это, используя
json_normalize
:Это позволяет избежать дорогостоящих функций применения ...
источник
.json
файлов, поступают из разных источников, и это не всегда одни и те же вложенные столбцы. Я пытался найти способ создать список столбцов, которые содержат dicts, но, похоже, не могу с этимfrom pandas.io.json import json_normalize
meta_prefix
иrecord_prefix
. Хотя я не могу заставить эту работу работать с моим фреймворком данных (окончательный фрейм данных в моем случае правильный, но я хотел бы применить префиксы).Попробуйте следующее: данные, возвращаемые из SQL, должны быть преобразованы в Dict. Или это могло быть
"Pollutant Levels"
сейчасPollutants'
источник
Ответ Мерлина лучше и очень просто, но нам не нужна лямбда-функция. Оценка словаря может быть проигнорирована одним из следующих двух способов, как показано ниже:
Способ 1: два шага
Способ 2: два вышеуказанных шага можно объединить за один раз:
источник
Я настоятельно рекомендую метод извлечения столбца «Загрязняющие вещества»:
df_pollutants = pd.DataFrame(df['Pollutants'].values.tolist(), index=df.index)
это намного быстрее чем
df_pollutants = df['Pollutants'].apply(pd.Series)
когда размер df велик.
источник
apply
весь фрейм данных, управляется пандами, но когда дело доходит доvalues
него, он играет только с тем,numpy ndarrays
что по сути быстрее из-за того, что он имеет чистыеc
реализации.Вы можете использовать
join
сpop
+tolist
. Производительность сопоставимаconcat
сdrop
+tolist
, но некоторые могут найти этот синтаксис для очистки:Бенчмаркинг другими методами:
источник
Однострочное решение следующее:
источник
my_df = pd.DataFrame.from_dict(my_dict, orient='index', columns=['my_col'])
.. правильно проанализировал бы dict (поместив каждый ключ dict в отдельный столбец df, а значения ключей - в строки df), поэтому dicts не будет сжиматься в один столбец в первую очередь.
источник
Я объединил эти шаги в методе, вам нужно передать только фрейм данных и столбец, содержащий расширяемый dict:
источник
источник