Peringatan Pengguna Python Pandas: Mengurutkan karena sumbu non-penggabungan tidak sejajar

93

Saya melakukan beberapa praktik kode dan menerapkan penggabungan bingkai data saat melakukan ini mendapatkan peringatan pengguna

/usr/lib64/python2.7/site-packages/pandas/core/frame.py:6201: FutureWarning: Mengurutkan karena sumbu non-penggabungan tidak sejajar. Versi panda yang akan datang akan berubah menjadi tidak mengurutkan secara default. Untuk menerima perilaku masa depan, berikan 'sort = True'. Untuk mempertahankan perilaku saat ini dan membungkam peringatan, berikan sortir = False

Pada baris kode ini: Bisakah Anda membantu mendapatkan solusi dari peringatan ini.

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
sumber

Jawaban:

136

tl; dr:

concatdan appendsaat ini mengurutkan indeks non-rangkaian (misalnya kolom jika Anda menambahkan baris) jika kolom tidak cocok. Di pandas 0.23, ini mulai menghasilkan peringatan; berikan parameter sort=Trueuntuk membungkamnya. Di masa mendatang, default akan berubah menjadi tidak diurutkan, jadi yang terbaik adalah menentukan salah satu sort=Trueatau Falsesekarang, atau lebih baik lagi memastikan bahwa indeks non-penggabungan Anda cocok.


Peringatan ini baru di panda 0.23.0 :

Di versi mendatang dari panda pandas.concat()dan DataFrame.append()tidak akan lagi mengurutkan sumbu non-penggabungan jika belum disejajarkan. Perilaku saat ini sama dengan yang sebelumnya (pengurutan), tetapi sekarang peringatan dikeluarkan ketika pengurutan tidak ditentukan dan sumbu non-penggabungan tidak sejajar, tautan .

Informasi lebih lanjut dari masalah github sangat lama tertaut , komentar oleh smcinerney :

Saat menggabungkan DataFrames, nama kolom diurutkan secara alfanumerik jika ada perbedaan di antara keduanya. Jika mereka identik di DataFrames, mereka tidak diurutkan.

Jenis ini tidak berdokumen dan tidak diinginkan. Tentu saja perilaku defaultnya harus no-sort.

Setelah beberapa waktu, parameter sortdiimplementasikan di pandas.concatdan DataFrame.append:

sort : boolean, default Tidak ada

Urutkan sumbu non-penggabungan jika belum disejajarkan saat penggabungan adalah 'luar'. Pengurutan default saat ini tidak digunakan lagi dan akan berubah menjadi tidak diurutkan di versi panda yang akan datang.

Explicitly pass sort = True untuk membungkam peringatan dan sortir. Secara eksplisit lulus sort = False untuk membungkam peringatan dan bukan mengurutkan.

Ini tidak berpengaruh saat join = 'inner', yang sudah mempertahankan urutan sumbu non-penggabungan.

Jadi jika kedua DataFrame memiliki kolom yang sama dalam urutan yang sama, tidak ada peringatan dan tidak ada penyortiran:

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

Tetapi jika DataFrames memiliki kolom yang berbeda, atau kolom yang sama dalam urutan yang berbeda, panda mengembalikan peringatan jika tidak ada parameter sortyang secara eksplisit ditetapkan ( sort=Noneadalah nilai default):

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: Mengurutkan karena sumbu non-penggabungan tidak sejajar.

   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

Jika DataFrames memiliki kolom yang berbeda, tetapi kolom pertama disejajarkan - kolom tersebut akan ditempatkan dengan benar satu sama lain (kolom adan bdari df1dengan adan bdari df2dalam contoh di bawah) karena keduanya ada di keduanya. Untuk kolom lain yang ada di satu tapi tidak kedua DataFrames, nilai yang hilang dibuat.

Terakhir, jika Anda lulus sort=True, kolom diurutkan secara alfanumerik. Jika sort=Falsedan DafaFrame kedua memiliki kolom yang tidak ada di kolom pertama, mereka ditambahkan ke akhir tanpa penyortiran:

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: Mengurutkan karena sumbu non-penggabungan tidak sejajar.

   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

Dalam kode Anda:

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
sumber
21
Saya kurang mengerti: 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. apa itu a non-concatenation axisdan seperti apa hasilnya? apakah kolom a dan kolom b akan tidak cocok? atau hanya urutan kolomnya saja yang berbeda?
penawaran tidak dapat ditolak
9
Tidak jelas apa is not alignedartinya - bisakah Anda mengomentarinya?
Mr_and_Mrs_D
1
Saya percaya alignedberarti bahwa level pada sumbu adalah sama: jika ada perbedaan dalam bentuk apa pun, mereka tidak lagi aligneddan akan memicu perilaku ini (misalnya jika level sumbu adalah ['c','b','a']dan ['a'])
Robert Muil
3
@RobertMuil Saya pikir menggunakan istilah di levelsini berpotensi membingungkan karena levelmemiliki arti khusus untuk dataframes pandas ketika ada MultiIndex. Dari yang saya pahami, aligneddalam konteks ini mengacu pada urutan indeks baris / kolom. Jadi jika urutan indeks sumbu non-penggabungan berbeda untuk dua bingkai Anda, maka Anda dapat menentukan apakah akan mempertahankan urutan di bingkai pertama yang dilewati, dan mengurutkan bingkai kedua agar cocok, atau untuk mengurutkan indeks KEDUA bingkai sebelum penggabungan. Ini juga merupakan area yang membingungkan bagi saya, jadi koreksi diterima!
ac24
Kolom disejajarkan saat tuple(df1.columns) == tuple(df2.columns). Sumbu non-penggabungan adalah sumbu (baris atau kolom) yang sejajar dengan jahitan di mana DataFrames sedang digabungkan.
BallpointSeben
107

Jawaban jezrael bagus, tetapi tidak menjawab pertanyaan yang saya miliki: Apakah mendapatkan tanda "urutkan" yang salah akan mengacaukan data saya dengan cara apa pun? Jawabannya tampaknya "tidak", Anda baik-baik saja.

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
sumber
apa sebenarnya yang diurutkan atau tidak diurutkan?
Ben
2
@Ben peringatan muncul ketika urutan kolom berbeda antara dataframe. Seperti yang Anda lihat jika sort = True maka kolom setelah penggabungan diurutkan menurut abjad
MP23
Dalam contoh ini tidak, tetapi jika Anda menggabungkan beberapa Seri atau DataFrames dengan DatetimeIndex, baris tidak lagi dalam urutan kronologis. Secara teknis datanya tidak kacau, tetapi hasil Anda mungkin lebih sulit dibaca.
hugovdberg