Ostrzeżenie użytkownika Python Pandas: sortowanie, ponieważ oś bez konkatenacji nie jest wyrównana

93

Robię trochę praktyki w kodzie i stosuję scalanie ramek danych, robiąc to, otrzymując ostrzeżenie użytkownika

/usr/lib64/python2.7/site-packages/pandas/core/frame.py:6201: FutureWarning: Sortowanie, ponieważ oś niezwiązana z konkatenacją nie jest wyrównana. Przyszła wersja pand zmieni się tak, aby nie sortować domyślnie. Aby zaakceptować przyszłe zachowanie, podaj 'sort = True'. Aby zachować bieżące zachowanie i wyciszyć ostrzeżenie, podaj sort = False

W tych wierszach kodu: Czy możesz pomóc w uzyskaniu rozwiązania tego ostrzeżenia.

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"]]
MishD
źródło

Odpowiedzi:

136

tl; dr:

concati appendobecnie sortuj indeks niekatenacyjny (np. kolumny, jeśli dodajesz wiersze), jeśli kolumny nie są zgodne. W pandach 0.23 zaczęło to generować ostrzeżenie; przekazać parametr, sort=Trueaby go wyciszyć. W przyszłości domyślnym zmieni się nie sortowania, więc najlepiej, aby określić albo sort=Truealbo Falseteraz, albo jeszcze lepiej upewnić się, że indeksy nie konkatenacji pasuje.


Ostrzeżenie jest nowe w pandach 0.23.0 :

W przyszłej wersji pand pandas.concat()i DataFrame.append()nie będzie już sortować osi bez konkatenacji, gdy nie jest już wyrównana. Bieżące zachowanie jest takie samo, jak poprzednie (sortowanie), ale teraz jest wyświetlane ostrzeżenie, gdy sortowanie nie jest określone, a oś nie-konkatenacji nie jest wyrównana, połącz .

Więcej informacji z powiązanego, bardzo starego numeru na githubie, komentarz smcinerney :

Podczas łączenia ramek DataFrames nazwy kolumn są sortowane alfanumerycznie, jeśli są między nimi jakieś różnice. Jeśli są identyczne w ramkach DataFrame, nie są sortowane.

Ten rodzaj jest nieudokumentowany i niechciany. Z pewnością domyślne zachowanie nie powinno być sortowane.

Po pewnym czasie parametr sortzostał zaimplementowany w pandas.concati DataFrame.append:

sort : boolean, default None

Sortuj osie bez konkatenacji, jeśli nie są już wyrównane, gdy sprzężenie jest „zewnętrzne”. Bieżące domyślne sortowanie jest przestarzałe i zmieni się na brak sortowania w przyszłych wersjach pand.

Jawnie podaj sort = True, aby wyciszyć ostrzeżenie i posortować. Jawnie podaj sort = False, aby wyciszyć ostrzeżenie i nie sortować.

Nie ma to wpływu, gdy join = 'inner', co już zachowuje kolejność osi bez konkatenacji.

Jeśli więc obie ramki DataFrame mają te same kolumny w tej samej kolejności, nie ma ostrzeżenia ani sortowania:

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

Ale jeśli ramki DataFrames mają różne kolumny lub te same kolumny w innej kolejności, pandy zwracają ostrzeżenie, jeśli żaden parametr nie sortjest jawnie ustawiony ( sort=Nonejest to wartość domyślna):

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: Sortowanie, ponieważ oś bez konkatenacji nie jest wyrównana.

   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

Jeśli DataFrames mają różne kolumny, ale pierwsze kolumny są wyrównane - będą one prawidłowo przypisany do siebie (kolumny ai bz df1z aa bz df2w poniższym przykładzie), ponieważ one istnieją w obu. W przypadku innych kolumn, które istnieją w jednej, ale nie w obu ramkach DataFrame, tworzone są braki danych.

Wreszcie, jeśli zdasz sort=True, kolumny są sortowane alfanumerycznie. Jeśli sort=Falsea druga ramka DafaFrame ma kolumny, których nie ma w pierwszej, są one dołączane na końcu bez sortowania:

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: Sortowanie, ponieważ oś bez konkatenacji nie jest wyrównana.

   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

W swoim kodzie:

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()
jezrael
źródło
21
Nie do końca rozumiem: 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. czym jest a non-concatenation axisi jak będzie wyglądał wynik? czy kolumny a i b będą niezgodne? czy tylko kolejność kolumn jest inna?
oferta nie może odmówić
9
Nie jest jasne, co to is not alignedznaczy - czy mógłbyś to skomentować?
Mr_and_Mrs_D
1
Wierzę alignedoznacza, że poziomy w osi są takie same: czy istnieje różnica dowolnego rodzaju, nie są one już alignedi wywoła to zachowanie (na przykład, jeśli oś poziomy ['c','b','a']i ['a'])
Robert Muil
3
@RobertMuil Myślę, że użycie tego terminu leveljest potencjalnie mylące, ponieważ levelma określone znaczenie dla ramek danych pandy, gdy istnieje MultiIndex. Z tego, co rozumiem, alignedw tym kontekście odnosi się do kolejności indeksu wierszy / kolumn. Więc jeśli kolejność indeksów osi bez konkatenacji jest inna dla twoich dwóch ramek, możesz określić, czy zachować kolejność w pierwszej przekazanej klatce i posortować drugą ramkę, aby pasowała, czy też posortować indeks OBU ramek przed konkatenacją. Dla mnie też jest to zagmatwane, więc poprawki mile widziane!
ac24
Kolumny są wyrównane, gdy tuple(df1.columns) == tuple(df2.columns). Oś braku konkatenacji to oś (wiersze lub kolumny) równoległa do szwów, wzdłuż których są zszywane ramki DataFrames.
BallpointBen
107

Odpowiedź jezraela jest dobra, ale nie odpowiedziałem na moje pytanie: Czy otrzymanie flagi „sort” zepsuje w jakikolwiek sposób moje dane? Najwyraźniej odpowiedź brzmi „nie”, tak czy inaczej nic ci nie jest.

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
RLC
źródło
co dokładnie jest posortowane, a co nie?
Ben
2
@Ben - ostrzeżenie pojawia się, gdy kolejność kolumn jest różna między ramkami danych. Jak widać, jeśli sort = True, to kolumny po konkatentacji są sortowane alfabetycznie
MP23
W tym przykładzie tak nie jest, ale jeśli połączysz wiele Series lub DataFrames z DatetimeIndex, wiersze nie są już w kolejności chronologicznej. Technicznie dane nie są pomieszane, ale wynik może być trudniejszy do odczytania.
hugovdberg