2016-12-01 3 views
0

У меня есть dataframe из двух столбцов. У одного из двух есть значение словаря, состоящего из нескольких ключей и значений. Я хотел бы расширить эти словарные ключи для разделения столбцов. Возможно ли это в пандах?Преобразование строк словарей в отдельные столбцы pandas

In [1]:print df 
Out[2]: 
    ID column_2 
0 1 {u'color':'blue',u'counts':10} 
1 3 {u'color':'red',u'counts':30} 
2 10 {u'color':'purple',u'counts':12} 
... 

к следующим желаемым результатам:

ID color counts 
0 1 'blue'  10 
1 3 'red'  30 
2 10 'purple' 12 
+2

Почему у вас есть столбец словарей, в первую очередь? Это не имеет никакого смысла. –

ответ

0

Независимо от того, есть ли у вас словарь в качестве типа данных в вашем dataframe (вероятно, не имеет смысла), это делает работу:

df2 = pd.concat([df, df.column_2.apply(lambda x: pd.Series(x))], axis=1) 
df2 

    ID       column_2 color counts 
0 1 {'counts': 10, 'color': 'blue'} blue  10 
1 3  {'counts': 30, 'color': 'red'}  red  30 
2 10 {'counts': 12, 'color': 'purple'} purple  12 

Тогда вы можете просто сделать df2 = df2[[x for x in df2.columns if x != 'column_2']]


Убедитесь, что у вас есть фактический dict в столбце, а не строковое представление dict. Например, когда я загружаю вам данные это строковое представление, так что я должен изменить, что:

df = pd.read_clipboard() 
df.column_2 = df.column_2.apply(lambda x: eval(x)) 
4

Обратите внимание, что вы можете сделать следующее:

In [3]: pd.DataFrame(df.col2.values.tolist()) 
Out[3]: 
    color counts 
0 blue  10 
1  red  30 
2 purple  12 

Так просто взломать его вместе с помощью concat из там:

In [4]: pd.concat((df.ID, pd.DataFrame(df.col2.values.tolist())),axis=1) 
Out[4]: 
    ID color counts 
0 1 blue  10 
1 3  red  30 
2 10 purple  12 

Timings:

In [132]: %timeit (pd.concat((df.ID, pd.DataFrame(df.column_2.tolist())),axis=1)) 
1 loop, best of 3: 339 ms per loop 

In [133]: %timeit (pd.concat((df.ID, pd.DataFrame(df.column_2.values.tolist())),axis=1)) 
1 loop, best of 3: 322 ms per loop 

In [134]: %timeit pd.concat([df, df.column_2.apply(lambda x: pd.Series(x))], axis=1) 
1 loop, best of 3: 1min 7s per loop 

Код для таймингов:

df = pd.DataFrame({'ID':[1,3,10], 
        'column_2':[{u'color':'blue',u'counts':10}, 
           {u'color':'red',u'counts':30}, 
           {u'color':'purple',u'counts':12}]}) 

df = pd.concat([df]*100000).reset_index(drop=True) 
#[300000 rows x 3 columns] 
print (df) 
+3

Быстрее используется 'pd.concat ((df.ID, pd.DataFrame (df.col2.values.tolist())), axis = 1)' – jezrael

+0

@jezrael Это интересно, и хотя я его не тестировал Пользуюсь твоим словом. Интересно, почему? –

+0

Я думаю, потому что он лучше работает с массивами numpy;) – jezrael

Смежные вопросы