Topic: Problema modifica colonna DataFrame Pandas  (Letto 2171 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline pato8

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Problema modifica colonna DataFrame Pandas
« il: Ottobre 01, 2015, 00:27 »
Ciao a tutti, sono nuovo nel forum! Ho urgentemente bisogno di aiuto!
Ho questo problema: sto cercando di riassegnare i valori di una colonna di un DataFrame tramite la seguente istruzione:
[codice]slicing_data.loc[:,"Timestamp"] = ts[/codice]
dove appunto la colonna da cambiare è Timestamp dove ts è una lista di lunghezza pari al numero di righe del DataFrame.
L'istruzione viene eseguita e la colonna assume i nuovi valori, ma esce un SettingWithCopyWarning dove mi consiglia di usare il metodo .loc, che già è usato!
Ho cercato ovunque in rete ma non sono riuscito a venirne a capo.
Mi basterebbe anche riuscire a evitare la stampa del messaggio di warning sullo standard output che è molto fastidioso: ho provato a catturare il warning con un try-except ma nulla.
Qualcuno ha idea su come risolvere questo problema?

Grazie in anticipo
« Ultima modifica: Ottobre 01, 2015, 00:29 da pato8 »

Offline Giornale di Sistema

  • python sapiens sapiens
  • ******
  • Post: 3.124
  • Punti reputazione: 4
    • Mostra profilo
    • Distillato di Python
Re: Problema modifica colonna DataFrame Pandas
« Risposta #1 il: Ottobre 01, 2015, 07:32 »
Mi basterebbe anche riuscire a evitare la stampa del messaggio di warning sullo standard output che è molto fastidioso

http://stackoverflow.com/questions/21560749/python-pandas-removing-settingwithcopywarning

Offline pato8

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #2 il: Ottobre 01, 2015, 10:08 »
L'ho già guardato. Il mio problema è che la colonna già esiste e devo sovrascrivere dei valori. Quello che potrei fare è cancellare la colonna e ricrearne un'altra con lo stesso nome. Però vorrei mantenere l'ordinamento, ovvero mettere "Timestamp" come prima colonna del Dataframe perché poi la vado a copiare in un file.
Come potrei fare?

Offline caronte

  • python erectus
  • ***
  • Post: 225
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #3 il: Ottobre 01, 2015, 20:58 »
scusami ma nel tuo erbivoro non ti funziona semplicemente una semplice assegnazione...
df['Timestamp'] = ts  ??

Offline pato8

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #4 il: Ottobre 02, 2015, 01:23 »
scusami ma nel tuo erbivoro non ti funziona semplicemente una semplice assegnazione...
df['Timestamp'] = ts  ??
Funziona ma mi lancia lo stesso warning. È veramente fastidioso vederlo a video..

Offline caronte

  • python erectus
  • ***
  • Post: 225
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #5 il: Ottobre 02, 2015, 13:05 »
Mha…normalmente questo è un classico change in place in un data frame, quindi non ti deve ritornare  nessuna copia e quindi nessun warning.  Ovviamente Python non ti da allarmi a cazzz..., e se trascuri  alla fine ti escono i casini…
Se tu visualizzi quel warning probabilmente il dataframe che stai cercando modificare è a sua volta una copia di un altro dataframe dal quale l’hai derivato, magari tramite uno slicing o peggio un chaining…controlla tutta la catena.
ps. quando postate --roba-- di questo genere è meglio accompagnarle con gli esempi riproducibili che vi danno il problema

Offline pato8

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #6 il: Ottobre 02, 2015, 20:48 »
Mha…normalmente questo è un classico change in place in un data frame, quindi non ti deve ritornare  nessuna copia e quindi nessun warning.  Ovviamente Python non ti da allarmi a cazzz..., e se trascuri  alla fine ti escono i casini…
Se tu visualizzi quel warning probabilmente il dataframe che stai cercando modificare è a sua volta una copia di un altro dataframe dal quale l’hai derivato, magari tramite uno slicing o peggio un chaining…controlla tutta la catena.
ps. quando postate --roba-- di questo genere è meglio accompagnarle con gli esempi riproducibili che vi danno il problema

Hai ragione, mi sono appena scritto. Comunque la catena è questa:
[codice]
for i in xrange(traces):
      slicing_data = data[i*n_ms:(i+1)*n_ms]
      slicing_data.loc[:,"Timestamp"] = ts
[/codice]
Praticamente faccio lo slice di un dataframe a blocchi di n_ms righe. e poi riassegno la colonna. La cosa strana è che il warning viene lanciato una volta sola e non per tutte le iterazioni. Ancora più strano è che non riesco a catturare il warning con un try-except.

Offline caronte

  • python erectus
  • ***
  • Post: 225
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #7 il: Ottobre 02, 2015, 22:42 »
ma ..no non è riproducibile…
infatti quando ho messo quel codice nel mio editor(che fa girare Python 3), e che è abbastanza pignolo: primo ha avuto da ridire sull’indentazione, pare non gli piaccia,   secondo mi ha stressato per non avergli detto niente di quel  --data--, non sa nenche che è un df, non ne conosce ne le dimensioni e ne sa cosa c’è dentro..

io comunque per pararmi il culo e tranquillizzarlo, ho abbozzato un df sia con variabili numeriche che d’altra –specie--, perché visto che hai scelto un df invece di una matrice presumo che contenga variabili di tipo differente…
poi gli ho dato corda…
--> Quel warning  spunta fuori  ogni volta che  nella nuova assegnazione ad una data iterazione  --slicing_data = data[i*n_ms:(i+1)*n_ms]  --- excedi il numero di rows…edit:{nello specifico quando ---sfori la memoria preallocata---} cosa che sto ipotizzando perché non mi hai dato un codice riproducibile,  da quell’assegnazione in poi Python di avvisa gentilmente che  stai creando una copia, in quanto stai eccedendo una dimensione di quel df.  Il piu delle volte questo approccio non è –-stimabile—riflettici su…e l’erbivoro  lo sa…
Ma alla fine, se ti da fastidio sto comportamento, vai con R…lui è piu sadico,  non ti dice niente…
« Ultima modifica: Ottobre 03, 2015, 00:59 da caronte »

Offline pato8

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #8 il: Ottobre 03, 2015, 10:56 »
Il codice è un poì lungo da postare tutto..ci sono una serie di chiamate a funzioni. Praticamente leggo un file csv e poi seleziono un certo numero di colonne che mi interessano e dopo faccio l'operazione sopra per spezzare il dataframe. Il numero di righe non viene superato perché quel traces è proprio il numero di blocchi ottenuto dal rapporto del numero di righe del dataframe ed n_ms.

P.S.
Cosa intendi con questo "erbivoro" di cui parli?

Offline caronte

  • python erectus
  • ***
  • Post: 225
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #9 il: Ottobre 03, 2015, 19:45 »
Quindi in definitiva a te interessa creare diversi  subsets  del df originale  …giusto?
Allora taglia la testa all’erbivoro (pandas) e digli chiaramente che desideri delle copie del df originale, cosi se la dovrebbe  finire...
[codice]
for i in range(traces):
    slicing_data = data[i*n_ms:(i+1)*n_ms].copy()
    slicing_data.loc[:, "Timestamp"] = ts
[/codice]
prova...
« Ultima modifica: Ottobre 03, 2015, 20:12 da caronte »

Offline riko

  • python deus
  • *
  • moderatore
  • Post: 7.453
  • Punti reputazione: 12
    • Mostra profilo
    • RiK0 Tech Temple
Re: Problema modifica colonna DataFrame Pandas
« Risposta #10 il: Ottobre 04, 2015, 00:49 »
Il codice è un poì lungo da postare tutto.

Non devi postare tutto. Devi fornire un esempio minimale che abbia queste proprieta':
1. mostri lo stesso problema del tuo programma
2. sia tale per cui verosimilmente risolvere il problema nell'esempio ti dia la soluzione (o almeno ti avvicini) alla soluzione del programma vero
3. non e' possibile (almeno facile) avere un esempio piu' piccolo che esponga lo stesso problema e che abbia la proprieta' 2

Devi anche fornire dati di input et similia, meglio se tutto funziona facendo copia e incolla in un Python standard.

Offline imbuto

  • python neanderthalensis
  • ****
  • Post: 462
  • Punti reputazione: 2
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #11 il: Ottobre 04, 2015, 13:34 »
By the way, visto che nessuno ha commentato:

La cosa strana è che il warning viene lanciato una volta sola e non per tutte le iterazioni. Ancora più strano è che non riesco a catturare il warning con un try-except.

Non’é strano, anzi è normale che non venga catturato da un try/except dal momento che si tratta di un Warning e non di una Exception.
Inoltre in genere i Warning relativi ad una line adì codice vengono lanciati una sola volta (a seconda delle impostazioni).


Hai ragione, mi sono appena scritto. Comunque la catena è questa:
[codice]
for i in xrange(traces):
      slicing_data = data[i*n_ms:(i+1)*n_ms]
      slicing_data.loc[:,"Timestamp"] = ts
[/codice]
Praticamente faccio lo slice di un dataframe a blocchi di n_ms righe. e poi riassegno la colonna. La cosa strana è che il warning viene lanciato una volta sola e non per tutte le iterazioni. Ancora più strano è che non riesco a catturare il warning con un try-except.

Il problema è semplice, tu vuoi riassegnare i valori nel DataFrame originale (a quanto ho capito) ma lo fai usando una copia.

[codice]
In [1]: import pandas as pd

In [2]: df = pd.DataFrame({'Column1': [1,2,3,4], 'Column2':[5,6,7,8]})

In [3]: df
Out[3]:
   Column1  Column2
0        1        5
1        2        6
2        3        7
3        4        8

In [4]: df1 = df[::2]

In [5]: df1['Column1']=1
/Users/mauro/anaconda/bin/ipython:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

In [6]: df
Out[6]:
   Column1  Column2
0        1        5
1        2        6
2        1        7
3        4        8

In [7]: df1
Out[7]:
   Column1  Column2
0        1        5
2        1        7
[/codice]

In effetti hai cambiato anche il DataFrame originale, ma il Warning ti avvisa che forse non era quello che volevi fare.

Hai poi tentato di usare loc, ma nel modo sbagliato:

[codice]
In [8]: df1.loc[:,'Column1']=6
/Users/mauro/anaconda/lib/python2.7/site-packages/pandas/core/indexing.py:490: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

In [9]: df
Out[9]:
   Column1  Column2
0        6        5
1        2        6
2        6        7
3        4        8

In [10]: df1
Out[10]:
   Column1  Column2
0        6        5
2        6        7
[/codice]

Non cambia nulla, stai ancora lavorando sulla slice e pandas ti lancia un Warning.

Se ben ho capito cosa cerchi, fai così, usa direttamente il DataFrame originale e riassegna inline:

[codice]
In [11]: df.loc[::2,'Column1']=7

In [12]: df
Out[12]:
   Column1  Column2
0        7        5
1        2        6
2        7        7
3        4        8
[/codice]

Se invece non vuoi cambiare il DataFrame originale, usa .copy() come suggerito.

[codice]
In [13]: df1 = df[::2].copy()

In [14]: df1['Column1']=100

In [15]: df
Out[15]:
   Column1  Column2
0        7        5
1        2        6
2        7        7
3        4        8

In [16]: df1
Out[16]:
   Column1  Column2
0      100        5
2      100        7
[/codice]

Questo almeno, per quanto ho capito. Come fatto notare, dovresti chiedere aiuto in modo più preciso.

Offline pato8

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re: Problema modifica colonna DataFrame Pandas
« Risposta #12 il: Ottobre 17, 2015, 16:19 »
Scusate se non mi sono fatto più sentire. Vi ringrazio per le delucidazioni.
Alla fine ho risolto aggiungendo un'altra colonna Timestamp in quanto i valori che c'erano nel dataframe originale non mi servivano più.
Comunque mi interessava la modifica solo sui blocchi singoli, non sul dataframe originale, anche se per il motivo che ho scritto sopra non mi avrebbe fatto differenza.