Группировка путем агрегирования и транспонирования в панд

#python #python-3.x #pandas #dataframe #pandas-groupby

Вопрос:

df=

 Genre Song          Singer               Playlist           Album
Rock  Evil Walks      AC/DC                 Music            For Those About To Rock We Salute You
Rock  Snowballed      AC/DC                 Music            For Those About To Rock We Salute You
Rock  C.O.D           AC/DC                 Music            For Those About To Rock We Salute You         
Rock  Perfect         Alanis Morissette     Music            Jagged Little Pill
Rock  Forgiven        Alanis Morissette     Music            Jagged Little Pill
Metal Sad But True    Apocalyptica          Music            Plays Metallica By Four Cellos
Metal All For You     Black Label Society   Music            Alcohol Fueled Brewtality Live! [Disc 1]
Blues Layla           Eric Clapton          Music            The Cream Of Clapton
Blues Crossroads      Eric Clapton          Music            The Cream Of Clapton
.......
......
....
Latin Etnia           Chico Science         Music            Afrociberdelia
 

Из всех жанров в области жанров мне нужно только рассмотреть «Рок», «Латынь», «Металл», «Блюз» и создать новый фрейм данных на основе следующих требований

а.сколько песен у певца из этого жанра (количество песен каждого жанра должно быть в отдельной колонке).

б.Подсчитайте, сколько альбомов у певца в данных.

c.Подсчитайте, сколько треков у певца в данных.

d.Подсчитайте, сколько плейлистов включает любую песню певца.

Желаемый Результат:

 Singer       Rock  Latin  Metal  Blues   CountofAlbums   CountofSongs  Count of Playlists
AC/DC         5      7    8      2         4                22             2
Metallica     8      0    22     0         6                30             6       
Iron Maiden   21     0    27     13        10               61             12
 

Я собирался создать один df для части a и один для частей b,c,d и объединить их.

Для частей b,c и d. Я думал о циклическом переборе имен певцов и использовании nunique для получения определенного количества, но не понимал, что цикл также будет каждый раз возвращать заголовки столбцов.

 mylist=list(set(df.Singer))
for i in mylist:
    temp=df[df['Singer']==i]
    df2=temp.nunique().to_frame().T
    
 

Для части А я собирался сгруппировать песни по жанрам, найти количество и сделать транспонирование

 mylist=list(set(df.Singer))
for i in mylist:
   group=df4.groupby('Genre_Name').agg(count=('Song','count'))
   newdf=group.T
 

Любая помощь будет очень признательна!

Ответ №1:

Можно сделать в одну строку, но это немного сложно…

 df = pd.DataFrame({
    'Genre':['Rock']*5 ['Metal']*2 ['Blues']*2 ['Latin'],
    'Song':['Evil Walks','Snowballed','C.O.D','Perfect','Forgiven','Sad But True',
    'All For You','Layla','Crossroads','Etnia'],
    'Singer':['AC/DC']*3 ['Alanis Morissette']*2 ['Apocalyptica'] ['Black Label Society'] ['Eric Clapton']*2 ['Chico Science'],
    'Playlist':['Music']*10,
    'Album':['For Those About To Rock We Salute You']*3 ['Jagged Little Pill']*2 ['Plays Metallica By Four Cellos'] ['Alcohol Fueled Brewtality Live! [Disc 1]'] ['The Cream Of Clapton']*2 ['Afrociberdelia']
    })

agg_df=df.groupby('Singer').agg({'Song':'count'})
agg_df=agg_df.join(df[['Singer','Album']].drop_duplicates().groupby('Singer').count())
agg_df=agg_df.join(df[['Singer','Playlist']].drop_duplicates().groupby('Singer').count())
agg_df=agg_df.join(df.reset_index()[['Singer','Genre','index']].groupby(['Singer','Genre']).count().rename({'index':'count'},axis=1).unstack().fillna(0).astype(np.int16))