Avviso utente Python Pandas: ordinamento perché l'asse di non concatenazione non è allineato


93

Sto facendo un po 'di pratica sul codice e applicando l'unione di frame di dati mentre lo faccio ricevendo un avviso per l'utente

/usr/lib64/python2.7/site-packages/pandas/core/frame.py:6201: FutureWarning: ordinamento perché l'asse di non concatenazione non è allineato. Una versione futura dei panda cambierà per non ordinare per impostazione predefinita. Per accettare il comportamento futuro, passare "sort = True". Per mantenere il comportamento corrente e silenziare l'avviso, passare sort = False

Su queste righe di codice: Puoi per favore aiutarci a ottenere la soluzione di questo avvertimento.

placement_video = [self.read_sql_vdx_summary, self.read_sql_video_km]
placement_video_summary = reduce(lambda left, right: pd.merge(left, right, on='PLACEMENT', sort=False), placement_video)


placement_by_video = placement_video_summary.loc[:, ["PLACEMENT", "PLACEMENT_NAME", "COST_TYPE", "PRODUCT",
                                                     "VIDEONAME", "VIEW0", "VIEW25", "VIEW50", "VIEW75",
                                                     "VIEW100",
                                                     "ENG0", "ENG25", "ENG50", "ENG75", "ENG100", "DPE0",
                                                     "DPE25",
                                                     "DPE50", "DPE75", "DPE100"]]

# print (placement_by_video)

placement_by_video["Placement# Name"] = placement_by_video[["PLACEMENT",
                                                            "PLACEMENT_NAME"]].apply(lambda x: ".".join(x),
                                                                                     axis=1)

placement_by_video_new = placement_by_video.loc[:,
                         ["PLACEMENT", "Placement# Name", "COST_TYPE", "PRODUCT", "VIDEONAME",
                          "VIEW0", "VIEW25", "VIEW50", "VIEW75", "VIEW100",
                          "ENG0", "ENG25", "ENG50", "ENG75", "ENG100", "DPE0", "DPE25",
                          "DPE50", "DPE75", "DPE100"]]

placement_by_km_video = [placement_by_video_new, self.read_sql_km_for_video]
placement_by_km_video_summary = reduce(lambda left, right: pd.merge(left, right, on=['PLACEMENT', 'PRODUCT'], sort=False),
                                       placement_by_km_video)

#print (list(placement_by_km_video_summary))
#print(placement_by_km_video_summary)
#exit()
# print(placement_by_video_new)
"""Conditions for 25%view"""
mask17 = placement_by_km_video_summary["PRODUCT"].isin(['Display', 'Mobile'])
mask18 = placement_by_km_video_summary["COST_TYPE"].isin(["CPE", "CPM", "CPCV"])
mask19 = placement_by_km_video_summary["PRODUCT"].isin(["InStream"])
mask20 = placement_by_km_video_summary["COST_TYPE"].isin(["CPE", "CPM", "CPE+", "CPCV"])
mask_video_video_completions = placement_by_km_video_summary["COST_TYPE"].isin(["CPCV"])
mask21 = placement_by_km_video_summary["COST_TYPE"].isin(["CPE+"])
mask22 = placement_by_km_video_summary["COST_TYPE"].isin(["CPE", "CPM"])
mask23 = placement_by_km_video_summary["PRODUCT"].isin(['Display', 'Mobile', 'InStream'])
mask24 = placement_by_km_video_summary["COST_TYPE"].isin(["CPE", "CPM", "CPE+"])

choice25video_eng = placement_by_km_video_summary["ENG25"]
choice25video_vwr = placement_by_km_video_summary["VIEW25"]
choice25video_deep = placement_by_km_video_summary["DPE25"]

placement_by_km_video_summary["25_pc_video"] = np.select([mask17 & mask18, mask19 & mask20, mask17 & mask21],
                                                  [choice25video_eng, choice25video_vwr, choice25video_deep])


"""Conditions for 50%view"""
choice50video_eng = placement_by_km_video_summary["ENG50"]
choice50video_vwr = placement_by_km_video_summary["VIEW50"]
choice50video_deep = placement_by_km_video_summary["DPE50"]

placement_by_km_video_summary["50_pc_video"] = np.select([mask17 & mask18, mask19 & mask20, mask17 & mask21],
                                                  [choice50video_eng,
                                                   choice50video_vwr, choice50video_deep])

"""Conditions for 75%view"""

choice75video_eng = placement_by_km_video_summary["ENG75"]
choice75video_vwr = placement_by_km_video_summary["VIEW75"]
choice75video_deep = placement_by_km_video_summary["DPE75"]

placement_by_km_video_summary["75_pc_video"] = np.select([mask17 & mask18, mask19 & mask20, mask17 & mask21],
                                                  [choice75video_eng,
                                                   choice75video_vwr,
                                                   choice75video_deep])

"""Conditions for 100%view"""

choice100video_eng = placement_by_km_video_summary["ENG100"]
choice100video_vwr = placement_by_km_video_summary["VIEW100"]
choice100video_deep = placement_by_km_video_summary["DPE100"]
choicecompletions = placement_by_km_video_summary['COMPLETIONS']

placement_by_km_video_summary["100_pc_video"] = np.select([mask17 & mask22, mask19 & mask24, mask17 & mask21, mask23 & mask_video_video_completions],
                                                          [choice100video_eng, choice100video_vwr, choice100video_deep, choicecompletions])



"""conditions for 0%view"""

choice0video_eng = placement_by_km_video_summary["ENG0"]
choice0video_vwr = placement_by_km_video_summary["VIEW0"]
choice0video_deep = placement_by_km_video_summary["DPE0"]

placement_by_km_video_summary["Views"] = np.select([mask17 & mask18, mask19 & mask20, mask17 & mask21],
                                                   [choice0video_eng,
                                                    choice0video_vwr,
                                                    choice0video_deep])


#print (placement_by_km_video_summary)
#exit()

#final Table

placement_by_video_summary = placement_by_km_video_summary.loc[:,
                             ["PLACEMENT", "Placement# Name", "PRODUCT", "VIDEONAME", "COST_TYPE",
                              "Views", "25_pc_video", "50_pc_video", "75_pc_video","100_pc_video",
                              "ENGAGEMENTS","IMPRESSIONS", "DPEENGAMENTS"]]

#placement_by_km_video = [placement_by_video_summary, self.read_sql_km_for_video]
#placement_by_km_video_summary = reduce(lambda left, right: pd.merge(left, right, on=['PLACEMENT', 'PRODUCT']),
                                       #placement_by_km_video)


#print(placement_by_video_summary)
#exit()
# dup_col =["IMPRESSIONS","ENGAGEMENTS","DPEENGAMENTS"]

# placement_by_video_summary.loc[placement_by_video_summary.duplicated(dup_col),dup_col] = np.nan

# print ("Dhar",placement_by_video_summary)

'''adding views based on conditions'''
#filter maximum value from videos

placement_by_video_summary_new = placement_by_km_video_summary.loc[
    placement_by_km_video_summary.reset_index().groupby(['PLACEMENT', 'PRODUCT'])['Views'].idxmax()]
#print (placement_by_video_summary_new)
#exit()
# print (placement_by_video_summary_new)
# mask22 = (placement_by_video_summary_new.PRODUCT.str.upper ()=='DISPLAY') & (placement_by_video_summary_new.COST_TYPE=='CPE')

placement_by_video_summary_new.loc[mask17 & mask18, 'Views'] = placement_by_video_summary_new['ENGAGEMENTS']
placement_by_video_summary_new.loc[mask19 & mask20, 'Views'] = placement_by_video_summary_new['IMPRESSIONS']
placement_by_video_summary_new.loc[mask17 & mask21, 'Views'] = placement_by_video_summary_new['DPEENGAMENTS']

#print (placement_by_video_summary_new)
#exit()
placement_by_video_summary = placement_by_video_summary.drop(placement_by_video_summary_new.index).append(
    placement_by_video_summary_new).sort_index()

placement_by_video_summary["Video Completion Rate"] = placement_by_video_summary["100_pc_video"] / \
                                                      placement_by_video_summary["Views"]

placement_by_video_final = placement_by_video_summary.loc[:,
                           ["Placement# Name", "PRODUCT", "VIDEONAME", "Views",
                            "25_pc_video", "50_pc_video", "75_pc_video", "100_pc_video",
                            "Video Completion Rate"]]

Risposte:


136

tl; dr:

concate appendattualmente ordina l'indice di non concatenazione (ad esempio le colonne se stai aggiungendo righe) se le colonne non corrispondono. In panda 0.23 questo ha iniziato a generare un avviso; passare il parametro sort=Trueper silenziarlo. In futuro l'impostazione predefinita cambierà in non ordinamento, quindi è meglio specificare sort=Trueo Falseora, o meglio ancora assicurarsi che gli indici di non concatenazione corrispondano.


L'avviso è nuovo in panda 0.23.0 :

In una versione futura di panda pandas.concat()e DataFrame.append()non ordinerà più l'asse di non concatenazione quando non è già allineato. Il comportamento corrente è lo stesso del precedente (ordinamento), ma ora viene emesso un avviso quando l'ordinamento non è specificato e l'asse di non concatenazione non è allineato, collegamento .

Maggiori informazioni dal vecchio problema di GitHub collegato , commento di smcinerney :

Quando si concatenano DataFrame, i nomi delle colonne vengono ordinati in ordine alfanumerico se ci sono differenze tra loro. Se sono identici su DataFrame, non vengono ordinati.

Questo tipo è non documentato e indesiderato. Certamente il comportamento predefinito dovrebbe essere no-sort.

Dopo qualche tempo il parametro è sortstato implementato in pandas.concate DataFrame.append:

ordinamento : booleano, predefinito Nessuno

Ordina l'asse di non concatenazione se non è già allineato quando il join è "esterno". L'attuale impostazione predefinita di ordinamento è deprecata e cambierà in non ordinamento in una versione futura di Panda.

Passa esplicitamente sort = True per silenziare l'avviso e ordinare. Passa esplicitamente sort = False per silenziare l'avviso e non ordinare.

Questo non ha effetto quando join = 'inner', che conserva già l'ordine dell'asse di non concatenazione.

Quindi, se entrambi i DataFrame hanno le stesse colonne nello stesso ordine, non ci sono avvisi né ordinamento:

df1 = pd.DataFrame({"a": [1, 2], "b": [0, 8]}, columns=['a', 'b'])
df2 = pd.DataFrame({"a": [4, 5], "b": [7, 3]}, columns=['a', 'b'])

print (pd.concat([df1, df2]))
   a  b
0  1  0
1  2  8
0  4  7
1  5  3

df1 = pd.DataFrame({"a": [1, 2], "b": [0, 8]}, columns=['b', 'a'])
df2 = pd.DataFrame({"a": [4, 5], "b": [7, 3]}, columns=['b', 'a'])

print (pd.concat([df1, df2]))
   b  a
0  0  1
1  8  2
0  7  4
1  3  5

Ma se i DataFrame hanno colonne diverse o le stesse colonne in un ordine diverso, pandas restituisce un avviso se nessun parametro sortè impostato esplicitamente ( sort=Noneè il valore predefinito):

df1 = pd.DataFrame({"a": [1, 2], "b": [0, 8]}, columns=['b', 'a'])
df2 = pd.DataFrame({"a": [4, 5], "b": [7, 3]}, columns=['a', 'b'])

print (pd.concat([df1, df2]))

FutureWarning: ordinamento perché l'asse di non concatenazione non è allineato.

   a  b
0  1  0
1  2  8
0  4  7
1  5  3

print (pd.concat([df1, df2], sort=True))
   a  b
0  1  0
1  2  8
0  4  7
1  5  3

print (pd.concat([df1, df2], sort=False))
   b  a
0  0  1
1  8  2
0  7  4
1  3  5

Se i DataFrame hanno colonne diverse, ma le prime colonne sono allineate, verranno assegnate correttamente l'una all'altra (colonne ae bda df1con ae bda df2nell'esempio seguente) perché esistono in entrambe. Per le altre colonne presenti in uno ma non in entrambi i DataFrame, vengono creati i valori mancanti.

Infine, se passi sort=True, le colonne vengono ordinate alfanumerico. Se sort=Falsee il secondo DafaFrame ha colonne che non sono nella prima, vengono aggiunte alla fine senza ordinamento:

df1 = pd.DataFrame({"a": [1, 2], "b": [0, 8], 'e':[5, 0]}, 
                    columns=['b', 'a','e'])
df2 = pd.DataFrame({"a": [4, 5], "b": [7, 3], 'c':[2, 8], 'd':[7, 0]}, 
                    columns=['c','b','a','d'])

print (pd.concat([df1, df2]))

FutureWarning: ordinamento perché l'asse di non concatenazione non è allineato.

   a  b    c    d    e
0  1  0  NaN  NaN  5.0
1  2  8  NaN  NaN  0.0
0  4  7  2.0  7.0  NaN
1  5  3  8.0  0.0  NaN

print (pd.concat([df1, df2], sort=True))
   a  b    c    d    e
0  1  0  NaN  NaN  5.0
1  2  8  NaN  NaN  0.0
0  4  7  2.0  7.0  NaN
1  5  3  8.0  0.0  NaN

print (pd.concat([df1, df2], sort=False))

   b  a    e    c    d
0  0  1  5.0  NaN  NaN
1  8  2  0.0  NaN  NaN
0  7  4  NaN  2.0  7.0
1  3  5  NaN  8.0  0.0

Nel tuo codice:

placement_by_video_summary = placement_by_video_summary.drop(placement_by_video_summary_new.index)
                                                       .append(placement_by_video_summary_new, sort=True)
                                                       .sort_index()

21
Non lo capisco bene: In a future version of pandas pandas.concat() and DataFrame.append() will no longer sort the non-concatenation axis when it is not already aligned. cos'è un non-concatenation axise come sarà il risultato? la colonna a e la colonna b non corrispondono? o solo l'ordine delle colonne è diverso?
un'offerta non può rifiutare il

9
Non è chiaro cosa is not alignedsignifichi - potresti commentarlo?
Mr_and_Mrs_D

1
Credo alignedsignifichi che i livelli nell'asse sono gli stessi: se c'è una differenza di qualsiasi tipo, non lo sono più alignede attiveranno questo comportamento (ad esempio se i livelli degli assi sono ['c','b','a']e ['a'])
Robert Muil

3
@RobertMuil Penso che l'uso del termine levelqui sia potenzialmente fonte di confusione poiché levelha un significato specifico per i dataframe dei panda quando c'è un MultiIndex. Da quanto ho capito, alignedin questo contesto si fa riferimento all'ordinamento dell'indice riga / colonna. Quindi, se l'ordine dell'indice dell'asse di non concatenazione è diverso per i due frame, è possibile specificare se mantenere l'ordine nel primo frame passato e ordinare il secondo frame in modo che corrisponda o ordinare l'indice di ENTRAMBI i frame prima della concatenazione. Questa è un'area confusa anche per me, quindi le correzioni sono benvenute!
ac24

Le colonne sono allineate quando tuple(df1.columns) == tuple(df2.columns). L'asse di non concatenazione è l'asse (righe o colonne) parallelo alle cuciture lungo le quali i DataFrame vengono cuciti insieme.
Ballpoint

107

La risposta di jezrael è buona, ma non ha risposto a una mia domanda: il flag "sort" errato rovinerà i miei dati in qualche modo? La risposta è apparentemente "no", stai bene comunque.

from pandas import DataFrame, concat

a = DataFrame([{'a':1,      'c':2,'d':3      }])
b = DataFrame([{'a':4,'b':5,      'd':6,'e':7}])

>>> concat([a,b],sort=False)
   a    c  d    b    e
0  1  2.0  3  NaN  NaN
0  4  NaN  6  5.0  7.0

>>> concat([a,b],sort=True)
   a    b    c  d    e
0  1  NaN  2.0  3  NaN
0  4  5.0  NaN  6  7.0

cosa viene ordinato esattamente o non ordinato?
Ben

2
@Ben viene visualizzato l'avviso quando l'ordine delle colonne è diverso tra i dataframe. Come puoi vedere se sort = True, le colonne dopo la concatentazione sono ordinate alfabeticamente
MP23

In questo esempio non è così, ma se si concatenano più Series o DataFrame con un DatetimeIndex le righe non sono più in ordine cronologico. Tecnicamente i dati non sono confusi, ma il risultato potrebbe essere più difficile da leggere.
hugovdberg
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.