Объединить строки в одном фрейме данных - PullRequest
3 голосов
/ 03 октября 2019

У меня есть фрейм данных, в который я хочу внести некоторые изменения. Вот пример:

d = {'username': ['a', 'a', 'b', 'a', 'a'],
     'state': ['AR', 'AZ', 'CA', 'CO', 'NY'],
     'status': ['ADD', 'ADD', 'REMOVE', 'ADD', 'REMOVE']}
df = pd.DataFrame(data=d)

Я знаю, как я могу группировать и объединять состояния:

df = df.fillna('').groupby(['username', 'status'], as_index=False)['state'] \
    .apply(lambda x: ','.join(set(x))) \
    .reset_index() \
    .rename({0: 'state'}, axis=1)

Но в конце у меня есть что-то подобное, но все еще не то, что мне нужно:

username  status     state
a         ADD        AR,AZ,CO
a         REMOVE     NY
b         REMOVE     CA

Я хочу подготовить этот окончательный отчет:

username  ADD      REMOVE
a         AR,AZ,CO NY   
b                  CA

Есть идеи?

Большое спасибо!

Ответы [ 2 ]

3 голосов
/ 03 октября 2019

Мы можем использовать pivot_table с пользовательскими aggfunc здесь:

piv = df.pivot_table(index='username', columns='status', values='state', aggfunc=','.join)

status         ADD REMOVE
username                 
a         AR,AZ,CO     NY
b              NaN     CA
3 голосов
/ 03 октября 2019

Вы близки, прежде чем reset_index используйте Series.unstack:

df1 = (df.fillna('')
         .groupby(['username', 'status'])['state'] \
         .apply(lambda x: ','.join(set(x)))
         .unstack(fill_value='')
         .reset_index()
         .rename_axis(None, axis=1))
print (df1)
  username       ADD REMOVE
0        a  AZ,AR,CO     NY
1        b               CA

Или используйте DataFrame.pivot_table с преобразованием индекса в столбец по reset_index и удаление имени столбца с помощью DataFrame.rename_axis:

df1 = (df.pivot_table(index='username', 
                     columns='status', 
                     values='state', 
                     aggfunc=lambda x: ','.join(set(x)), 
                     fill_value='')
         .reset_index()
         .rename_axis(None, axis=1))

print (df1)
  username       ADD REMOVE
0        a  AZ,AR,CO     NY
1        b               CA

РЕДАКТИРОВАТЬ:

Возможно решение с удалением set s, если использовать DataFrame.drop_duplicates по 3 столбцам:

Изменены данные выборки для лучшего объяснения:

d = {'username': ['a', 'a', 'b', 'a', 'a', 'a'],
     'state': ['AR', 'AZ', 'CA', 'CO', 'NY', 'NY'],
     'status': ['ADD', 'ADD', 'REMOVE', 'ADD', 'REMOVE','REMOVE']}
df = pd.DataFrame(data=d)
print (df)
  username state  status
0        a    AR     ADD
1        a    AZ     ADD
2        b    CA  REMOVE
3        a    CO     ADD
4        a    NY  REMOVE
5        a    NY  REMOVE <- added row

df1 = (df.pivot_table(index='username', 
                     columns='status', 
                     values='state', 
                     aggfunc=lambda x: ','.join(set(x)), 
                     fill_value='')
         .reset_index()
         .rename_axis(None, axis=1))

print (df1)
  username       ADD REMOVE
0        a  AZ,AR,CO     NY
1        b               CA

df1 = (df.drop_duplicates(['username','status','state'])
         .pivot_table(index='username', 
                     columns='status', 
                     values='state', 
                     aggfunc= ','.join, 
                     fill_value='')
         .reset_index()
         .rename_axis(None, axis=1))

print (df1)
  username       ADD REMOVE
0        a  AZ,AR,CO     NY
1        b               CA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...