¿Qué sucede cuando modifico un dataframe de pandas de la siguiente manera?

tratando de entender este comportamiento (por qué ocurre; y si fue intencional, entonces, ¿cuál fue la motivación para hacerlo de esta manera)?

Así que creo un dataframe

np.random.seed(0) df = pd.DataFrame(np.random.random((4,2))) 0 1 0 0.548814 0.715189 1 0.602763 0.544883 2 0.423655 0.645894 3 0.437587 0.891773 

y puedo hacer referencia a columnas como tal

 df.columns = ['a','b'] df.a 0 0 0.548814 1 0.602763 2 0.423655 3 0.437587 

Incluso puedo hacer, lo que creo que es una nueva columna.

  df.third = pd.DataFrame(np.random.random((4,1))) 

pero df sigue siendo

 df 0 1 0 0.548814 0.715189 1 0.602763 0.544883 2 0.423655 0.645894 3 0.437587 0.891773 

sin embargo, df.third también existe (pero no puedo verlo en mi visor de variables en Spyder)

 df.third 0 0 0.118274 1 0.639921 2 0.143353 3 0.944669 

Si quisiera agregar una tercera columna, tendría que hacer lo siguiente

 df['third'] = pd.DataFrame(np.random.random((4,1))) ab third 0 0.548814 0.715189 0.568045 1 0.602763 0.544883 0.925597 2 0.423655 0.645894 0.071036 3 0.437587 0.891773 0.087129 

Entonces, mi pregunta es ¿qué sucede cuando hago df.third versus df [‘third’]?

Debido a que agregó el third como un atributo, debe dejar de acceder a las columnas como un atributo y usar siempre df['third'] para evitar un comportamiento ambiguo.

Debería adquirir el hábito de acceder y asignar siempre las columnas usando df[col_name] , esto es para evitar problemas como

 df.mean = some_calc() 

Bueno, el problema aquí es que la mean es un método para un DataFrame

Entonces has sobrescrito un método con algún valor computado.

El problema aquí es que esto fue parte del diseño como una conveniencia y los pandas para el libro de análisis de datos y algunas de las primeras presentaciones de video en línea mostraron esto como una forma de asignar una nueva columna, pero los errores sutiles pueden ser tan generalizados que realmente deberían ser prohibido y eliminado de la OMI

En serio, no puedo enfatizar esto lo suficiente, dejar de referirme a las columnas como un atributo , es un error grave para mí y, lamentablemente, todavía veo muchas respuestas publicadas que muestran este uso.

Puedes ver que no se agrega una nueva columna:

 In [97]: df.third = pd.DataFrame(np.random.random((4,1))) df.columns Out[97]: Index(['a', 'b'], dtype='object') 

Puedes ver que el third fue agregado como un atributo:

 In [98]: df.__dict__ Out[98]: {'_data': BlockManager Items: Index(['a', 'b'], dtype='object') Axis 1: Int64Index([0, 1, 2, 3], dtype='int64') FloatBlock: slice(0, 2, 1), 2 x 4, dtype: float64, '_iloc': , '_item_cache': {}, 'is_copy': None, 'third': 0 0 0.844821 1 0.286501 2 0.459170 3 0.243452} 

Puede ver que tiene un __data , __data , Axis 1 etc., pero también tiene 'third' que es un atributo

Creo que agrega el atributo tercero al objeto de dataframe de pandas. Si desea agregar la columna con el nombre ‘tercero’, debe hacer esto:

 df['third'] = pd.DataFrame(np.random.random((4,1)))