Сгруппировать и перенести в панд, питона - PullRequest
0 голосов
/ 15 мая 2018

Кадр данных имеет

ID  col  col2   col3   col4

1   A    50      S      1
1   A    52      M      4
1   B    45      N      8
1   C    18      S      7

Блок данных хочет

ID  col  colA   colB   colC   colD   colE   colF

1   A    50     52      S      M       1      4
1   B    45     NULL    N     NULL     8     NULL
1   C    18     NULL    S     NULL     7     NULL

Мне нужна 1 строка для каждого уникального идентификатора + столбец (идентификатор группы и столбец).Если имеется несколько записей на ID + col (максимум может быть 2, не более), тогда поместите первое значение col2 в colA и второе значение в colB, поместите первое значение col3 в colC и второе значение в colD, поместите первоезначение col4 в colE и второе значение в colF.Если для ID + col есть только одна запись, то для col2 введите значение в colA, а colB будет нулевым и т. Д.

Я попытался сначала создать счетчик:

df['COUNT'] = df.groupby(['ID','col']).cumcount()+1

Отсюда Iнамеревался просто добавить столбец, чтобы сказать

if count=1 then df['colA']=df.col2
if count=2 then df['colB']=df.col2

.. но это все равно приведет к тому же количеству строк, что и исходный df.

Ответы [ 3 ]

0 голосов
/ 15 мая 2018

Вы можете использовать groupby с apply(pd.Series)

df.groupby(['ID','col']).col2.apply(list).apply(pd.Series).add_prefix('col').reset_index()
Out[404]: 
   ID col  col0  col1
0   1   A  50.0  52.0
1   1   B  45.0   NaN
2   1   C  18.0   NaN
0 голосов
/ 15 мая 2018

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

import pandas as pd
import numpy as np

df = pd.DataFrame({'ID':[1,1,1,1], 
                  'Col1':['A','A','B','C'],
                 'Col2':[50,52,45,18]})

df = df.groupby(['ID','Col1']).agg({'Col2':['first','last']})
df.columns = ["_".join(x) for x in df.columns.ravel()]
df = df.reset_index()
df['Col2_last'] = np.where(df.Col2_first == df.Col2_last, float('nan'), df.Col2_last)

print(df)
0 голосов
/ 15 мая 2018

Я думаю, что нужно set_index с unstack:

df['COUNT'] = df.groupby(['ID','col']).cumcount()+1

df = df.set_index(['ID','col', 'COUNT'])['col2'].unstack().add_prefix('col').reset_index()
print (df)
COUNT  ID col  col1  col2
0       1   A  50.0  52.0
1       1   B  45.0   NaN
2       1   C  18.0   NaN

Или:

c = df.groupby(['ID','col']).cumcount()+1

df = df.set_index(['ID','col', c])['col2'].unstack().add_prefix('col').reset_index()
print (df)
   ID col  col1  col2
0   1   A  50.0  52.0
1   1   B  45.0   NaN
2   1   C  18.0   NaN

EDIT:

Для нескольких столбцов решение немного изменено, потому что работа с MultiIndex в столбцах:

df['COUNT'] = (df.groupby(['ID','col']).cumcount()+1).astype(str)

#remove col2
df = df.set_index(['ID','col', 'COUNT']).unstack()
#flatten Multiindex
df.columns = df.columns.map('_'.join)
df = df.reset_index()
print (df)
   ID col  col2_1  col2_2 col3_1 col3_2  col4_1  col4_2
0   1   A    50.0    52.0      S      M     1.0     4.0
1   1   B    45.0     NaN      N   None     8.0     NaN
2   1   C    18.0     NaN      S   None     7.0     NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...