Unpickling dictionary che contiene i dataframe dei panda genera AttributeError: l'oggetto 'Dataframe' non ha l'attributo '_data'

Aug 24 2020

Ho una classe che esegue analisi e allega i risultati, che sono dataframe panda, come attributi dell'oggetto:

>>> print(test.image.locate_DF)
              y          x       mass  ...    raw_mass        ep  frame
0     60.177142  59.788709  33.433414  ...  242.080256       NaN      0
1     60.651991  59.773904  33.724308  ...  242.355784       NaN      1
2     60.790437  60.190234  31.117164  ...  236.276671       NaN      2
3     60.771933  60.048123  33.558372  ...  240.981395       NaN      3
4     60.251282  59.775139  31.881009  ...  239.239022       NaN      4
...         ...        ...        ...  ...         ...       ...    ...
7212  68.186380  76.477449  18.122817  ...  176.523091       NaN   9410
7213  68.764444  76.574091  17.486454  ...  173.448306       NaN   9415
7214  68.191152  76.473477  17.402975  ...  172.848119  0.868326   9429
7215  67.034103  76.025885  17.010951  ...  170.928067 -0.600854   9431
7216  68.583276  75.309592  17.852992  ...  178.271558       NaN   9432

Successivamente, salvo tutti gli attributi dell'oggetto importanti in un dizionario e lo metto in salamoia per un uso successivo:

def save_parameters(self, filepath):
        
        param_dict = {}

    try:
            self.image.locate_DF
        except AttributeError:
            pass
        else:
            param_dict['optical_locate_DF'] = self.image.locate_DF

    with open(filepath, 'wb') as handle:
            pickle.dump(param_dict, handle, 5)

Quando provo a caricare quel file in salamoia, non ho alcun problema, il dataframe si carica perfettamente:

>>> test.save_parameters('test.pickle')
>>> with open('test.pickle', 'rb') as handle:
...     result = pickle.load(handle)
...
>>> print(result.keys())
dict_keys(['optical_path', 'optical_feature_diameter', 'optical_feature_minmass', 'optical_locate_DF', 'electrical_path', 'electrical_raw_data', 'electrical_processed_data', 'electrical_mean_voltage'])
>>> print(result['optical_locate_DF'])
              y          x       mass  ...    raw_mass        ep  frame
0     60.177142  59.788709  33.433414  ...  242.080256       NaN      0
1     60.651991  59.773904  33.724308  ...  242.355784       NaN      1
2     60.790437  60.190234  31.117164  ...  236.276671       NaN      2
3     60.771933  60.048123  33.558372  ...  240.981395       NaN      3
4     60.251282  59.775139  31.881009  ...  239.239022       NaN      4
...         ...        ...        ...  ...         ...       ...    ...
7212  68.186380  76.477449  18.122817  ...  176.523091       NaN   9410
7213  68.764444  76.574091  17.486454  ...  173.448306       NaN   9415
7214  68.191152  76.473477  17.402975  ...  172.848119  0.868326   9429
7215  67.034103  76.025885  17.010951  ...  170.928067 -0.600854   9431
7216  68.583276  75.309592  17.852992  ...  178.271558       NaN   9432

[7217 rows x 9 columns]

Tuttavia, dopo aver eseguito la mia analisi su un gruppo di questi file su un hpc, e quindi aver provato ad aprire lo stesso file in salamoia (ha un nome diverso ora ma è lo stesso file mostrato sopra, con la stessa analisi eseguita su di esso), ottengo ha generato un errore di attributo da parte dei panda. Dichiara che il dataframe non ha l'attributo "_data". Il dizionario ha le stesse chiavi e le chiavi che non sono un dataframe vengono stampate senza problemi:

>>> resultfile = '../results/diam_15_minmass_17_dist_50_mem_5000_tracklength_500/R9_DNA_50mV_001.pickle'
>>> with open(resultfile, 'rb') as handle:
...     result = pickle.load(handle)
...
>>> print(result.keys())
dict_keys(['optical_path', 'optical_feature_diameter', 'optical_feature_minmass', 'optical_locate_DF', 'optical_tracking_distance', 'optical_tracking_memory', 'optical_tracking_DF', 'optical_kinetics_DF', 'electrical_path', 'electrical_raw_data', 'electrical_processed_data', 'electrical_mean_voltage'])
>>> print(result['optical_locate_DF'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/stevenvanuytsel/miniconda3/envs/simultaneous_measurements/lib/python3.8/site-packages/pandas/core/frame.py", line 680, in __repr__
    self.to_string(
  File "/Users/stevenvanuytsel/miniconda3/envs/simultaneous_measurements/lib/python3.8/site-packages/pandas/core/frame.py", line 801, in to_string
    formatter = fmt.DataFrameFormatter(
  File "/Users/stevenvanuytsel/miniconda3/envs/simultaneous_measurements/lib/python3.8/site-packages/pandas/io/formats/format.py", line 593, in __init__
    self.max_rows_displayed = min(max_rows or len(self.frame), len(self.frame))
  File "/Users/stevenvanuytsel/miniconda3/envs/simultaneous_measurements/lib/python3.8/site-packages/pandas/core/frame.py", line 1041, in __len__
    return len(self.index)
  File "/Users/stevenvanuytsel/miniconda3/envs/simultaneous_measurements/lib/python3.8/site-packages/pandas/core/generic.py", line 5270, in __getattr__
    return object.__getattribute__(self, name)
  File "pandas/_libs/properties.pyx", line 63, in pandas._libs.properties.AxisProperty.__get__
  File "/Users/stevenvanuytsel/miniconda3/envs/simultaneous_measurements/lib/python3.8/site-packages/pandas/core/generic.py", line 5270, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute '_data'

Ho esaminato il manuale di pickle e un sacco di domande SO, ma non riesco a scoprire cosa sta andando storto qui. Qualcuno ha un'idea di come risolvere questo problema e anche se posso ancora accedere a quei dati?

Risposte

9 BodoB Aug 25 2020 at 15:23

Ho avuto lo stesso problema. Ho generato un dataframe Pandas in un ambiente con Pandas 1.1.1 e l'ho salvato in un file pickle.

with open('file.pkl', 'wb') as f:
    pickle.dump(data_frame_object, f)

Dopo averlo rimosso in un'altra sessione e aver stampato il dataframe, ho ricevuto lo stesso errore. Alcuni test in ambienti diversi hanno mostrato il seguente schema:

  • ambiente con Panda> = 1.1.0: funziona
  • ambiente con Pandas == 1.0.5: messaggio di errore come sopra
  • ambiente con Panda == 1.0.3: il kernel si arresta in modo anomalo

Ho ricevuto lo stesso errore utilizzando il formato HDF5, quindi sembra essere un problema di compatibilità con il dataframe e le diverse versioni di Pandas.

L'aggiornamento di Panda alla 1.1.1 negli ambienti interessati ha risolto il problema per me.

5 Steven Aug 24 2020 at 22:30

Dopo un lungo e doloroso processo di controllo incrociato delle versioni dei moduli, ho scoperto che questo errore era causato da un aggiornamento nella versione panda. Il mio Mac esegue ancora Panda 1.0.5, mentre HPC esegue Panda 1.1.0. Apparentemente, c'è una mancata corrispondenza tra i due (non sono sicuro se sia subito dopo il decapaggio o anche per altri formati di file utilizzati per il salvataggio).

1 LimingFang Nov 05 2020 at 05:34

Forse il problema è stato risolto.
Emmm, ma voglio ancora aggiungere alcuni commenti.

Salvo il file pkl sul server, ma quando lo carico sul mio MAC, si è bloccato, mostrando 'Dataframe' object has no attribute '_data'

Infine, ho scoperto che i panda sul mio Mac sono 1.0.5 ma 1.1.5 sul server. Quando l'ho aggiornato all'ultimo, ha funzionato.