we can use pandas pivot_table for this problem
your data looks like this
>>> data = {'Name': ['Kathy','Kathy','James','Henry','Henry','Henry'],
'Degree': ['Biology','Biology','Chemistry','Business','Business','Business'],
'AM_Class': ['Bio101', np.nan, np.nan, 'Bus100', np.nan, np.nan],
'PM_Class': [np.nan, 'Chem101', 'Chem101', np.nan, 'Math100', np.nan],
'Online_Class': [np.nan, np.nan, np.nan, np.nan, np.nan, 'Acct100'],
}
>>> df = pd.DataFrame(data)
>>> print(df)
Name Degree AM_Class PM_Class Online_Class
0 Kathy Biology Bio101 NaN NaN
1 Kathy Biology NaN Chem101 NaN
2 James Chemistry NaN Chem101 NaN
3 Henry Business Bus100 NaN NaN
4 Henry Business NaN Math100 NaN
5 Henry Business NaN NaN Acct100
First we can replace all NaN with null string
>>> df.fillna('', inplace=True)
>>> print(df)
Name Degree AM_Class PM_Class Online_Class
0 0 Biology Bio101
1 1 Biology Chem101
2 2 Chemistry Chem101
3 3 Business Bus100
4 4 Business Math100
5 5 Business Acct100
I am doing this because while using pivot_table function I would like to use np.sum function which will concatenate strings in the pandas.series . Having the np.nan as it is will raise exception.
Now lets make the pivot table with Name being the group-by column.
>>> df2 = pd.pivot_table(data=df, index=['Name'], aggfunc={'Degree':np.unique, 'AM_Class':np.sum, 'PM_Class':np.sum, 'Online_Class':np.sum})
>>> print(df2)
AM_Class Degree Online_Class PM_Class
Name
Henry Bus100 Business Acct100 Math100
James Chemistry Chem101
Kathy Bio101 Biology Chem101
We have to replace the nulls with np.nan - since that is the format that is asked for.
>>> df2.replace('', np.nan, inplace=True)
>>> print(df2)
AM_Class Degree Online_Class PM_Class
Name
Henry Bus100 Business Acct100 Math100
James NaN Chemistry NaN Chem101
Kathy Bio101 Biology NaN Chem101
Observing the new dataframe df2, it seems we have to make the following changes
- Since the name column has become the Index - we have to make a Name column
- Add a RangeIndex
- Column order has to be restored
>>> df2['Name'] = df2.index
>>> cols = [ 'Name', 'Degree', 'AM_Class', 'PM_Class', 'Online_Class']
>>> df2 = df2[cols]
>>> print(df2)
Name Degree AM_Class PM_Class Online_Class
Name
Henry Henry Business Bus100 Math100 Acct100
James James Chemistry NaN Chem101 NaN
Kathy Kathy Biology Bio101 Chem101 NaN
>>> df2.set_index(pd.RangeIndex(start=0,stop=3,step=1), inplace=True)
>>> print(df2)
Name Degree AM_Class PM_Class Online_Class
0 Henry Business Bus100 Math100 Acct100
1 James Chemistry NaN Chem101 NaN
2 Kathy Biology Bio101 Chem101 NaN