2016-09-07 2 views
4

Скажем, мои данные выглядит следующим образом:Панды - Создание нескольких столбцов похож на pd.get_dummies

df = pd.DataFrame({'color': ['red', 'blue', 'green', 'red', 'blue', 'blue'], 'line': ['sunday', 'sunday', 'monday', 'monday', 'monday', 'tuesday'], 
       'group': ['1', '1', '2', '1', '1', '1'], 'value': ['a', 'b', 'a', 'c', 'a', 'b']}) 

    color group line value 
0 red  1  sunday a 
1 blue  1  sunday b 
2 green  2  monday a 
3 red  1  monday c 
4 blue  1  monday a 
5 blue  1 tuesday b 

По сути, то, что я хочу, чтобы получить список строк для каждого цвета. Например, я хочу, чтобы цвет красный отображал каждую строку и значение, связанные с ним, в своем столбце. Фокус в том, что я также хочу показать другие строки, связанные с цветами из той же группы. Соответствующие значения для них будут «недопустимы». Таким образом, я хочу, чтобы мой выход выглядеть следующим образом:

color line_1 line_1_value line_2 line_2_value line_3  line_3_value 
0 red  sunday  a   monday  c   tuesday not eligible 
1 blue sunday  b   monday  a   tuesday   b 
2 green monday  c  

Есть некоторые ~ 50000 уникальных «цвета», что мне нужно сделать это для. Я уверен, что это нечто относительно простое, но у меня пока нет знаний или навыков, чтобы понять это. Любая помощь будет оценена!

ответ

0

Бросьте столбец не нужно, и добавить столбец, чтобы получить уникальный субиндексам в цвет:

df = df.drop('group', axis=1) 
df['index_by_color'] = df.groupby('color').cumcount() 

    color  line value index_by_color 
0 red sunday  a    0 
1 blue sunday  b    0 
2 green monday  a    0 
3 red monday  c    1 
4 blue monday  a    1 
5 blue tuesday  b    2 

Используйте pivot_table, чтобы получить ориентацию данных, которые вы хотите:

df.pivot_table(index='color', columns=['index_by_color'], aggfunc=lambda x:x.iloc[0]) 

        line     value 
index_by_color  0  1  2  0  1  2 
color 
blue   sunday monday tuesday  b  a  b 
green   monday None  None  a None None 
red    sunday monday  None  a  c None 

Вещь о aggfunc=lambda x:x.iloc[0] заключается в том, чтобы уменьшить числовые числовые данные в виде определенного значения, а первый элемент подкадра достаточен в соответствии с единственностью вашей структуры данных.

Переупорядочьте колонки иерархического индекс:

res = res.sort_index(axis=1, level=1) 

        line value line value  line value 
index_by_color  0  0  1  1  2  2 
color 
blue   sunday  b monday  a tuesday  b 
green   monday  a None None  None None 
red    sunday  a monday  c  None None 

Остальные части тривиальны очистки в зависимости от точного представления вам нужно, как cumcount()+1, если вам нужно, чтобы начать нумерацию с 1 вместо 0, записи/расплющить столбец имена, как вы хотите res.columns =['_'.join([l0, str(l1)]) for l0,l1 in res.columns] или эквивалент и т.д.

+0

Это кло se к тому, что я ищу; однако он не учитывает линии, которые связаны с другим цветом в группе. Таким образом, Line_2 для «красного цвета» должен показывать вторник, а соответствующее значение должно показывать «не подходит» – tbg0001

+0

. В качестве первого шага измените ваш фреймворк, добавив «не подходящий» в столбец значений для каждой группы, затем отбросьте группу и перейдите по алгоритму выше , Основная идея заключается в том, чтобы подготовить ваш фреймворк со всем, что вам нужно, перед тем, как применить опорный стержень. Вы видите здесь логику? – Boud

+0

Мне удалось выяснить, как добавить дополнительные записи в конец моего фрейма. Все это было включено в одну функцию для будущих целей. Спасибо за вашу помощь! – tbg0001

0

Рассмотрим Объединить два поворачиваются с обработкой в ​​глубину имени столбца:

df['count'] = df.groupby('color').cumcount() + 1 

pvt1 = df.pivot(columns='count', index='color', values='line').reset_index().fillna('') 
pvt1.columns = ['color'] + ['line_'+str(c) for c in pvt1.columns[1:]] 

pvt2 = df.pivot(columns='count', index='color', values='value').reset_index().fillna('') 
pvt2.columns = ['color'] + ['line_'+str(c)+'_value' for c in pvt2.columns[1:]] 

pvtdf = pd.merge(pvt1, pvt2, on=['color']) 
pvtdf = pvtdf[[c for c in sorted(pvtdf.columns)]] 

# color line_1 line_1_value line_2 line_2_value line_3 line_3_value 
# 0 blue sunday   b monday   a tuesday   b 
# 1 green monday   a           
# 2 red sunday   a monday   c      
+0

Это близко к тому, что я ищу; однако он не учитывает линии, которые связаны с другим цветом в группе. Поэтому Line_3 для «красного» должен показывать вторник, а соответствующее значение должно показывать «не подходит». – tbg0001

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