Pandas: dividir la lista en la columna en varias filas

Tengo una pregunta sobre la división de una lista en una columna de dataframe en varias filas.

Digamos que tengo este dataframe:

Job position Job type id 0 [6] [1] 3 1 [2, 6] [3, 6, 5] 4 2 [1] [9] 43 

Me gustaría cada combinación de números, por lo que el resultado final sería:

  id Job position Job type 0 3 6.0 1.0 1 4 2.0 3.0 2 4 2.0 6.0 3 4 2.0 5.0 4 4 6.0 3.0 5 4 6.0 6.0 6 4 6.0 5.0 7 43 1.0 9.0 

Porque ahora mismo me sale este resultado:

  id Job position Job type 0 3 6.0 1.0 1 4 2.0 3.0 2 4 6.0 6.0 3 4 NaN 5.0 4 43 1.0 9.0 

Para obtener el resultado anterior, hice:

 df = df.set_index(['id']) (df.apply(lambda x: pd.DataFrame(x.tolist(),index=x.index) .stack() .rename(x.name)).reset_index()) 

De manera similar a la sugerencia de Scott Boston, le sugiero que explote las columnas por separado y luego las combine.

Por ejemplo, para ‘Job position’:

 >>> df['Job position'].apply(pd.Series).reset_index().melt(id_vars='index').dropna()[['index', 'value']].set_index('index') value index 0 6.0 1 2.0 2 1.0 1 6.0 

Y, todos juntos:

 df = pd.DataFrame({'Job position': [[6], [2, 6], [1]], 'Job type': [[1], [3, 6, 5], [9]], 'id': [3, 4, 43]}) jobs = df['Job position'].apply(pd.Series).reset_index().melt(id_vars='index').dropna()[['index', 'value']].set_index('index') types = df['Job type'].apply(pd.Series).reset_index().melt(id_vars='index').dropna()[['index', 'value']].set_index('index') >>> pd.merge( pd.merge( jobs, types, left_index=True, right_index=True), df[['id']], left_index=True, right_index=True).rename(columns={'value_x': 'Job positions', 'value_y': 'Job type'}) Job positions Job type id 0 6.0 1.0 3 1 2.0 3.0 4 1 2.0 6.0 4 1 2.0 5.0 4 1 6.0 3.0 4 1 6.0 6.0 4 1 6.0 5.0 4 2 1.0 9.0 43 

Usa una comprensión

 pd.DataFrame([ [p, t, i] for P, T, i in df.values for p in P for t in T ], columns=df.columns) Job position Job type id 0 6 1 3 1 2 3 4 2 2 6 4 3 2 5 4 4 6 3 4 5 6 6 4 6 6 5 4 7 1 9 43 

Alternativas a la iteración sobre values

 pd.DataFrame([ [p, t, i] for P, T, i in df.itertuples(index=False) for p in P for t in T ], columns=df.columns) 

 z = zip(df['Job position'], df['Job type'], df['id']) pd.DataFrame([ [p, t, i] for P, T, i in z for p in P for t in T ], columns=df.columns) 

Para generalizar esta solución para acomodar cualquier número de columnas.

 pd.DataFrame([ [p, t] + a for P, T, *a in df.values for p in P for t in T ], columns=df.columns) Job position Job type id 0 6 1 3 1 2 3 4 2 2 6 4 3 2 5 4 4 6 3 4 5 6 6 4 6 6 5 4 7 1 9 43 

Desde el constructor del dataframe

 s1=df.Jobposition.str.len() s2=df.Jobtype.str.len() pd.DataFrame({'id':df.id.repeat(s1*s2), 'Jobposition':np.concatenate([np.repeat(x,y) for x,y in zip(df.Jobposition,s2)]), 'Jobtype':np.concatenate(np.repeat(df.Jobtype,s1).values)}) Jobposition Jobtype id 0 6 1 3 1 2 3 4 1 2 6 4 1 2 5 4 1 6 3 4 1 6 6 4 1 6 5 4 2 1 9 43 
 import itertools dfres = pd.DataFrame([j+(i[2],) for i in df.values for j in itertools.product(*i[0:2])] ,columns=df.columns) Job position Job type id 0 6 1 3 1 2 3 4 2 2 6 4 3 2 5 4 4 6 3 4 5 6 6 4 6 6 5 4 7 1 9 43