2017-01-18 5 views
2

У меня есть рамка данных pandas с двумя столбцами: item и value. Столбец value имеет значения как список кортежей, где первым элементом является поле, а второй элемент - это счетчик.Редизайн dataframe in pandas

**item value** 
item1 
item2 
item3 [('f1', 10L), ('f3', 5L)] 
item4 [('f4', 2L)] 
item5 [('f5', 1L)] 

Мне нужно развернуть/переделать dataframe в следующей форме.

**item f1 f3 f4 f5** 
item1    
item2    
item3 10 5  
item4   2 
item5    1 

Есть ли какая-либо функция в пандах, где это можно сделать быстро?

ответ

2

Поскольку вы смешали тип списков и np.nan, которые не итерация, вы можете сделать проверку типа, если значение является список кортежи затем вызвать pd.Series на нем после преобразования его в словаре, в противном случае построить пустой серии объекта:

import numpy as np 
import pandas as pd 
lst = [np.nan, np.nan, 
     [('f1', 10), ('f3', 5)], 
     [('f4', 2)], 
     [('f5', 1)]] 

df = pd.DataFrame({"item": ["item"+str(i) for i in range(1,6)], "value": let}) 

pd.concat([df.item, df['value'].apply(lambda x: pd.Series(dict(x)) if type(x) == list else pd.Series([]))], axis = 1) 

enter image description here

+0

OP может потребоваться более обобщенное решение. Там может быть больше значений и элементов, чем простой пост. – Parfait

+0

@Parfait Это, скорее всего. Я буду ждать, пока ОП выяснит. – Psidom

+0

Правда, есть больше значений. Тот, что в моем оригинальном посте - это просто игрушечный пример. – learner

1

Рассмотрят пререкания данных, строит список словарей, разделив для данных и nondata, затем конкатенации их вместе с сводными таблицами. Это может быть более обобщенным для любого числа и комбинации типов f:

import numpy as np 
import pandas as pd 

df = pd.DataFrame({'item':['item1', 'item2', 'item3', 'item4', 'item5'], 
        'value':['', '', [('f1', 10), ('f3', 5)], [('f4', 2)], [('f5', 1)]]}) 

# ACTUAL DATA 
data = [{'fcols': i[0], 'value': i[1], 'item': row['item']} 
     for ix, row in df.iterrows() if len(row['value']) > 0 for i in row['value']] 
newdf = pd.DataFrame(data).pivot_table(index='item', values='value', columns='fcols').reset_index() 

# NON-DATA 
fcols = [i[0] for f in df['value'].tolist() if len(f) > 0 for i in f] 
nondata = [{'value': np.nan, 'item': row['item'], 'fcols':f} 
      for ix, row in df.iterrows() if row['value'] == '' for f in fcols]  
nondf = pd.DataFrame(nondata).pivot_table(index='item', values='value', columns='fcols').reset_index() 

# COMBINED DF 
newdf = pd.concat([nondf,newdf]).rename_axis(None, axis=1).reset_index(drop=True) 

print(newdf) 

#  item f1 f3 f4 f5 
# 0 item1 NaN NaN NaN NaN 
# 1 item2 NaN NaN NaN NaN 
# 2 item3 10.0 5.0 NaN NaN 
# 3 item4 NaN NaN 2.0 NaN 
# 4 item5 NaN NaN NaN 1.0