I have a dataset that's currently one row per applicant that I need to be one row per application. There are three columns, app_0, app_1, and app_2, which contain the names of the programs to which they are applying. If they've applied to one program, there's a string of the program name in app_0, and app_1 & app_2 are missing; if they've applied to two programs, there are strings of program names in app_0 & app_1 and app_2 is missing; and if they've applied to three programs all three columns contain strings. The three corresponding accepted columns work the same way. Here's an example dataframe:
import pandas as pd
import numpy as np
pd.DataFrame({
'id': [0, 1, 2, 3, 4],
'test_score': [350, 450, 500, 325, 433],
'gender': ['F', 'F', 'M', 'M', 'F'],
'app_0': ['A', 'B', 'D', 'C', 'B'],
'app_1': ['B', np.nan, np.nan, 'B', np.nan],
'app_2': [np.nan, np.nan, np.nan, 'A', np.nan],
'accepted_0': [True, False, False, True, False],
'accepted_1': [False, np.nan, np.nan, True, np.nan],
'accepted_2': [np.nan, np.nan, np.nan, False, np.nan]
})
In the dataframe with one row per application, I would want one column with the string of the program applied to, and one column indictating if that application were accepted or denied. The rest of the columns I would want copied in cases where an applicant submitted more than one application. The final dataframe should look like this (row order doesn't matter):
pd.DataFrame({
'id': [0, 1, 2, 3, 4, 0, 3, 3],
'test_score': [350, 450, 500, 325, 433, 350, 325, 325],
'gender': ['F', 'F', 'M', 'M', 'F', 'F', 'M', 'M'],
'app': ['A', 'B', 'D', 'C', 'B', 'B', 'B', 'A'],
'accepted': [True, False, False, True, False, False, True, False]
})
I'm looking for the simplest and most computationally efficient (i.e., probably not Iterrows) way to do this in Pandas. Would it be a pivot dataframe, and then a second command to fill in copied values from the old dataframe? Would unstack() be useful here? Thanks!