Deepcopy pandas DataFrame que contiene objetos de python (como listas)

Necesita ayuda para entender la asignación de variables, punteros, …

Lo siguiente es reproducible.

import pandas as pd df = pd.DataFrame({ 'listData': [ ['c', 'f', 'd', 'a', 'e', 'b'], [5, 2, 1, 4, 3] ]}) df['listDataSort'] = df['listData'] 

da:

  listData listDataSort 0 [c, f, d, a, e, b] [c, f, d, a, e, b] 1 [5, 2, 1, 4, 3] [5, 2, 1, 4, 3] 

Si solo quiero ordenar las listas en la columna listDataSort , podría intentar:

 df['listDataSort'].apply(lambda l: l.sort()) df 

Sin embargo, eso ordena las listas en ambas columnas, en el lugar.

  listData listDataSort 0 [a, b, c, d, e, f] [a, b, c, d, e, f] 1 [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] 

Puedo arreglar esto haciendo en cambio:

 df = pd.DataFrame({ 'listData': [ ['c', 'f', 'd', 'a', 'e', 'b'], [5, 2, 1, 4, 3] ]}) df['listDataSort'] = df['listData'].apply(sorted) 

dando:

  listData listDataSort 0 [c, f, d, a, e, b] [a, b, c, d, e, f] 1 [5, 2, 1, 4, 3] [1, 2, 3, 4, 5] 

Al asignar df a una variable diferente, digamos que df2 todavía cambia todo a la lista de fonts original. Además, ¿cómo puedo crear un nuevo dataframe basado en un dataframe existente para poder realizar cambios en el nuevo dataframe sin realizar los mismos cambios en el dataframe existente?

 df = pd.DataFrame({ 'listData': [ ['c', 'f', 'd', 'a', 'e', 'b'], [5, 2, 1, 4, 3] ]}) df2 = df print('\ndf\n', df) print('\ndf2\n', df2) df2['listDataSort'] = df2['listData'] print('\ndf\n', df) print('\ndf2\n', df2) df2['listDataSort'].apply(lambda l: l.sort()) print('\ndf\n', df) print('\ndf2\n', df2) 

huellas dactilares:

 df listData 0 [c, f, d, a, e, b] 1 [5, 2, 1, 4, 3] df2 listData 0 [c, f, d, a, e, b] 1 [5, 2, 1, 4, 3] df listData listDataSort 0 [c, f, d, a, e, b] [c, f, d, a, e, b] 1 [5, 2, 1, 4, 3] [5, 2, 1, 4, 3] df2 listData listDataSort 0 [c, f, d, a, e, b] [c, f, d, a, e, b] 1 [5, 2, 1, 4, 3] [5, 2, 1, 4, 3] df listData listDataSort 0 [a, b, c, d, e, f] [a, b, c, d, e, f] 1 [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] df2 listData listDataSort 0 [a, b, c, d, e, f] [a, b, c, d, e, f] 1 [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] 

además:

 df = pd.DataFrame({ 'listData': [ ['c', 'f', 'd', 'a', 'e', 'b'], [5, 2, 1, 4, 3] ]}) print('\ndf\n', df) df3 = df df3['listDataSort'] = df3['listData'].apply(sorted) print('\ndf\n', df) print('\ndf3\n', df3) 

huellas dactilares:

 df listData 0 [c, f, d, a, e, b] 1 [5, 2, 1, 4, 3] df listData listDataSort 0 [c, f, d, a, e, b] [a, b, c, d, e, f] 1 [5, 2, 1, 4, 3] [1, 2, 3, 4, 5] df3 listData listDataSort 0 [c, f, d, a, e, b] [a, b, c, d, e, f] 1 [5, 2, 1, 4, 3] [1, 2, 3, 4, 5] 

Cuando corres

 df['listDataSort'] = df['listData'] 

Todo lo que hace es copiar las referencias de las listas a nuevas columnas. Esto significa que solo se realiza una copia superficial y ambas columnas hacen referencia a las mismas listas. Por lo tanto, cualquier cambio en una columna probablemente afectará a otra.

Puede usar una lista de comprensión sorted que devuelve una copia de los datos. Esta debería ser la opción más fácil para ti.

 df['listDataSort'] = [sorted(x) for x in df['listDataSort']] df listData listDataSort 0 [c, f, d, a, e, b] [a, b, c, d, e, f] 1 [5, 2, 1, 4, 3] [1, 2, 3, 4, 5] 

Ahora, cuando se trata del problema de hacer una copia de todo el DataFrame, las cosas son un poco más complicadas. Yo recomendaría deepcopy :

 import copy df2 = df.apply(copy.deepcopy)