Tengo un marco de datos de pandas de la siguiente manera
fruit_name | color -----------+------- apple | red banana | yellow orange | orange
Usando este marco de datos, quiero crear un nuevo marco de datos de la siguiente manera
name | fruit ------+------- Ben | ['apple', 'banana', 'orange'] Alex | ['apple', 'banana', 'orange'] Jude | ['apple', 'banana', 'orange'] May | ['apple', 'banana', 'orange'] ...
Para esto, probé lo siguiente
new_df = pd.DataFrame(columns=['name', 'fruit'] new_df['name'] = students['name'] new_df['fruit'] = fruits['fruits_name'].to_list()
me sale el siguiente mensaje de error
ValueError: Length of values (3) does not match length of index (10)
Quiero mi resultado final de la siguiente manera
name | fruit ------+------- Ben | apple Ben | banana Ben | orange Alex | apple Alex | banana Alex | orange ...
Pensé que usaría la función de explosión una vez que tenga una columna de listas. Pero estoy atascado obteniendo el marco de datos con la columna de listas.
Lo que está buscando en realidad se llama combinación cruzada , disponible en Pandas 1.2.0+:
new_df = students[['name']].merge(fruits[['fruit_name']], how='cross')
Producción:
name fruit_name 0 Ben apple 1 Ben banana 2 Ben orange 3 Alex apple 4 Alex banana 5 Alex orange 6 Jude apple 7 Jude banana 8 Jude orange 9 May apple 10 May banana 11 May orange
Tenga en cuenta que si está atascado con la versión anterior, use la misma clave para fusionar:
new_df = (students[['name']].assign(key=1) .merge(fruits[['fruit_name']].assign(key=1), on='key') .drop('key', axis=1) )
La razón por la que obtiene el error ValueError: Length of values (3) does not match length of index (10)
es porque está tratando de insertar la lista de frutas como una columna. Para convertirlo en una lista anidada, puede usar np.repeat o como se muestra a continuación:
fruit_list = ['apple', 'banana', 'orange'] names = ['Ben', 'Alex', 'Jude', 'May'] fruit_df = pd.DataFrame(columns=['name', 'fruit']) fruit_df['name'] = names fruit_df['fruit'] = [fruit_list for _ in range(len(names))] # make a nested fruit list for every name
eso da:
>>> fruit_df.head(2) name fruit 0 Ben [apple, banana, orange] 1 Alex [apple, banana, orange]
como usted está preguntando. y luego puedes
>>> fruit_df.explode('fruit') name fruit 0 Ben apple 0 Ben banana 0 Ben orange 1 Alex apple 1 Alex banana 1 Alex orange 2 Jude apple 2 Jude banana 2 Jude orange 3 May apple 3 May banana 3 May orange