Dalam proses menjawab pertanyaan ini untuk diri saya sendiri, saya belajar banyak hal, dan saya ingin mengumpulkan katalog contoh dan penjelasan.
Jawaban spesifik dari levelsargumen akan sampai pada akhir.
pandas.concat: Manual yang Hilang
Tautan ke Dokumentasi Saat Ini
Mengimpor dan menentukan objek
import pandas as pd
d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), index=[2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), index=[1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), index=[1, 3])
s1 = pd.Series([1, 2], index=[2, 3])
s2 = pd.Series([3, 4], index=[1, 2])
s3 = pd.Series([5, 6], index=[1, 3])
Argumen
objs
Argumen pertama yang kami temukan adalah objs:
objs : urutan atau pemetaan objek Seri, DataFrame, atau Panel Jika dict dilewatkan, kunci yang diurutkan akan digunakan sebagai argumen kunci, kecuali jika dilewatkan, dalam hal ini nilainya akan dipilih (lihat di bawah). Objek None apa pun akan dijatuhkan secara diam-diam kecuali semuanya adalah None dalam hal ini ValueError akan dimunculkan
- Kami biasanya melihat ini digunakan dengan daftar
Seriesatau DataFrameobjek.
- Saya akan menunjukkan bahwa itu
dictbisa sangat berguna juga.
- Generator juga dapat digunakan dan dapat berguna saat digunakan
mapseperti dimap(f, list_of_df)
Untuk saat ini, kami akan tetap menggunakan daftar beberapa objek DataFramedan yang Seriesditentukan di atas. Saya akan menunjukkan bagaimana kamus dapat dimanfaatkan untuk memberikan MultiIndexhasil yang sangat berguna nanti.
pd.concat([d1, d2])
A B C D
2 0.1 0.2 0.3 NaN
3 0.1 0.2 0.3 NaN
1 NaN 0.4 0.5 0.6
2 NaN 0.4 0.5 0.6
axis
Argumen kedua yang kami temui adalah axisyang nilai defaultnya adalah 0:
sumbu : {0 / 'indeks', 1 / 'kolom'}, default 0 Sumbu yang akan digabung.
Dua DataFramed dengan axis=0(ditumpuk)
Untuk nilai 0atau indexkami bermaksud mengatakan: "Sejajarkan sepanjang kolom dan tambahkan ke indeks".
Seperti yang ditunjukkan di atas di mana kami menggunakan axis=0, karena 0adalah nilai default, dan kami melihat bahwa indeks d2memperluas indeks d1meskipun ada tumpang tindih nilai 2:
pd.concat([d1, d2], axis=0)
A B C D
2 0.1 0.2 0.3 NaN
3 0.1 0.2 0.3 NaN
1 NaN 0.4 0.5 0.6
2 NaN 0.4 0.5 0.6
Dua DataFrames dengan axis=1(berdampingan)
Untuk nilai 1atau columnskami bermaksud mengatakan: "Sejajarkan sepanjang indeks dan tambahkan ke kolom",
pd.concat([d1, d2], axis=1)
A B C B C D
1 NaN NaN NaN 0.4 0.5 0.6
2 0.1 0.2 0.3 0.4 0.5 0.6
3 0.1 0.2 0.3 NaN NaN NaN
Kita dapat melihat bahwa indeks yang dihasilkan adalah gabungan dari indeks dan kolom yang dihasilkan adalah perpanjangan dari kolom dari d1kolom d2.
Dua (atau Tiga) Seriesdengan axis=0(ditumpuk)
Saat menggabungkan pandas.Seriesbersama axis=0, kami mendapatkan kembali a pandas.Series. Nama yang dihasilkan Seriesakan menjadi Nonekecuali semua Seriesyang digabungkan memiliki nama yang sama. Perhatikan 'Name: A'kapan kita mencetak hasilnya Series. Jika tidak ada, kita bisa menganggap Seriesnamanya None.
| | | pd.concat(
| pd.concat( | pd.concat( | [s1.rename('A'),
pd.concat( | [s1.rename('A'), | [s1.rename('A'), | s2.rename('B'),
[s1, s2]) | s2]) | s2.rename('A')]) | s3.rename('A')])
-------------- | --------------------- | ---------------------- | ----------------------
2 1 | 2 1 | 2 1 | 2 1
3 2 | 3 2 | 3 2 | 3 2
1 3 | 1 3 | 1 3 | 1 3
2 4 | 2 4 | 2 4 | 2 4
dtype: int64 | dtype: int64 | Name: A, dtype: int64 | 1 5
| | | 3 6
| | | dtype: int64
Dua (atau Tiga) Seriesdengan axis=1(berdampingan)
Saat menggabungkan pandas.Seriesbersama axis=1, itu adalah nameatribut yang kita rujuk untuk menyimpulkan nama kolom dalam hasil pandas.DataFrame.
| | pd.concat(
| pd.concat( | [s1.rename('X'),
pd.concat( | [s1.rename('X'), | s2.rename('Y'),
[s1, s2], axis=1) | s2], axis=1) | s3.rename('Z')], axis=1)
---------------------- | --------------------- | ------------------------------
0 1 | X 0 | X Y Z
1 NaN 3.0 | 1 NaN 3.0 | 1 NaN 3.0 5.0
2 1.0 4.0 | 2 1.0 4.0 | 2 1.0 4.0 NaN
3 2.0 NaN | 3 2.0 NaN | 3 2.0 NaN 6.0
Dicampur Seriesdan DataFramedengan axis=0(ditumpuk)
Saat melakukan penggabungan a Seriesdan DataFramebersama axis=0, kami mengonversi semua Seriesmenjadi satu kolom DataFrames.
Perhatikan secara khusus bahwa ini adalah rangkaian bersama axis=0; itu berarti memperluas indeks (baris) sambil meratakan kolom. Pada contoh di bawah ini, kita melihat index menjadi [2, 3, 2, 3]yang merupakan penambahan indeks tanpa pandang bulu. Kolom tidak tumpang tindih kecuali saya memaksa penamaan Serieskolom dengan argumen ke to_frame:
pd.concat( |
[s1.to_frame(), d1]) | pd.concat([s1, d1])
------------------------- | ---------------------
0 A B C | 0 A B C
2 1.0 NaN NaN NaN | 2 1.0 NaN NaN NaN
3 2.0 NaN NaN NaN | 3 2.0 NaN NaN NaN
2 NaN 0.1 0.2 0.3 | 2 NaN 0.1 0.2 0.3
3 NaN 0.1 0.2 0.3 | 3 NaN 0.1 0.2 0.3
Anda bisa melihat hasilnya pd.concat([s1, d1])sama seperti jika saya telah melakukan to_framesendiri.
Namun, saya dapat mengontrol nama kolom yang dihasilkan dengan parameter ke to_frame. Mengganti nama Seriesdengan renamemetode tidak mengontrol nama kolom dalam hasil DataFrame.
pd.concat( | pd.concat( | pd.concat(
[s1.to_frame('X'), d1]) | [s1.rename('X'), d1]) | [s1.to_frame('B'), d1])
---------------------------- | -------------------------- | ----------------------------
A B C X | 0 A B C | A B C
2 NaN NaN NaN 1.0 | 2 1.0 NaN NaN NaN | 2 NaN 1.0 NaN
3 NaN NaN NaN 2.0 | 3 2.0 NaN NaN NaN | 3 NaN 2.0 NaN
2 0.1 0.2 0.3 NaN | 2 NaN 0.1 0.2 0.3 | 2 0.1 0.2 0.3
3 0.1 0.2 0.3 NaN | 3 NaN 0.1 0.2 0.3 | 3 0.1 0.2 0.3
Dicampur Seriesdan DataFramedengan axis=1(berdampingan)
Ini cukup intuitif. Seriesnama kolom default ke pencacahan Seriesobjek tersebut ketika nameatribut tidak tersedia.
| pd.concat(
pd.concat( | [s1.rename('X'),
[s1, d1], | s2, s3, d1],
axis=1) | axis=1)
------------------- | -------------------------------
0 A B C | X 0 1 A B C
2 1 0.1 0.2 0.3 | 1 NaN 3.0 5.0 NaN NaN NaN
3 2 0.1 0.2 0.3 | 2 1.0 4.0 NaN 0.1 0.2 0.3
| 3 2.0 NaN 6.0 0.1 0.2 0.3
join
Argumen ketiga adalah joinyang menjelaskan apakah gabungan yang dihasilkan harus gabungan luar (default) atau gabungan dalam.
join : {'inner', 'outer'}, default 'outer'
Bagaimana menangani indeks pada sumbu lain.
Ternyata, tidak ada opsi leftatau rightkarena pd.concatdapat menangani lebih dari dua objek untuk digabungkan.
Dalam kasus d1dan d2, opsinya terlihat seperti:
outer
pd.concat([d1, d2], axis=1, join='outer')
A B C B C D
1 NaN NaN NaN 0.4 0.5 0.6
2 0.1 0.2 0.3 0.4 0.5 0.6
3 0.1 0.2 0.3 NaN NaN NaN
inner
pd.concat([d1, d2], axis=1, join='inner')
A B C B C D
2 0.1 0.2 0.3 0.4 0.5 0.6
join_axes
Argumen keempat adalah hal yang memungkinkan kita melakukan leftpenggabungan dan lainnya.
join_axes : daftar objek Indeks Indeks
khusus yang akan digunakan untuk sumbu n - 1 lainnya daripada melakukan logika himpunan dalam / luar.
Gabung Kiri
pd.concat([d1, d2, d3], axis=1, join_axes=[d1.index])
A B C B C D A B D
2 0.1 0.2 0.3 0.4 0.5 0.6 NaN NaN NaN
3 0.1 0.2 0.3 NaN NaN NaN 0.7 0.8 0.9
Gabung Kanan
pd.concat([d1, d2, d3], axis=1, join_axes=[d3.index])
A B C B C D A B D
1 NaN NaN NaN 0.4 0.5 0.6 0.7 0.8 0.9
3 0.1 0.2 0.3 NaN NaN NaN 0.7 0.8 0.9
ignore_index
ignore_index : boolean, default False
Jika True, jangan gunakan nilai indeks di sepanjang sumbu penggabungan. Sumbu yang dihasilkan akan diberi label 0, ..., n - 1. Ini berguna jika Anda adalah objek penggabungan di mana sumbu penggabungan tidak memiliki informasi pengindeksan yang berarti. Perhatikan nilai indeks pada sumbu lain masih dihormati dalam gabungan.
Seperti ketika saya menumpuk d1di atas d2, jika saya tidak peduli dengan nilai indeks, saya dapat mengatur ulang atau mengabaikannya.
| pd.concat( | pd.concat(
| [d1, d2], | [d1, d2]
pd.concat([d1, d2]) | ignore_index=True) | ).reset_index(drop=True)
--------------------- | ----------------------- | -------------------------
A B C D | A B C D | A B C D
2 0.1 0.2 0.3 NaN | 0 0.1 0.2 0.3 NaN | 0 0.1 0.2 0.3 NaN
3 0.1 0.2 0.3 NaN | 1 0.1 0.2 0.3 NaN | 1 0.1 0.2 0.3 NaN
1 NaN 0.4 0.5 0.6 | 2 NaN 0.4 0.5 0.6 | 2 NaN 0.4 0.5 0.6
2 NaN 0.4 0.5 0.6 | 3 NaN 0.4 0.5 0.6 | 3 NaN 0.4 0.5 0.6
Dan saat menggunakan axis=1:
| pd.concat(
| [d1, d2], axis=1,
pd.concat([d1, d2], axis=1) | ignore_index=True)
------------------------------- | -------------------------------
A B C B C D | 0 1 2 3 4 5
1 NaN NaN NaN 0.4 0.5 0.6 | 1 NaN NaN NaN 0.4 0.5 0.6
2 0.1 0.2 0.3 0.4 0.5 0.6 | 2 0.1 0.2 0.3 0.4 0.5 0.6
3 0.1 0.2 0.3 NaN NaN NaN | 3 0.1 0.2 0.3 NaN NaN NaN
keys
Kita dapat mengirimkan daftar nilai skalar atau tupel untuk menetapkan nilai tupel atau skalar ke MultiIndex yang sesuai. Panjang daftar yang lolos harus sama dengan jumlah item yang digabungkan.
keys : sequence, default None
Jika melewati beberapa level, harus berisi tupel. Buat indeks hierarki menggunakan kunci yang diteruskan sebagai tingkat terluar
axis=0
Saat menggabungkan Seriesobjek axis=0(memperluas indeks).
Kunci tersebut, menjadi level awal baru dari sebuah MultiIndexobjek di atribut index.
pd.concat([s1, s2, s3], keys=['A', 'B', 'C']) pd.concat([s1, s2], keys=['A', 'B'])
---------------------------------------------- -------------------------------------
A 2 1 A 2 1
3 2 3 2
B 1 3 B 1 3
2 4 2 4
C 1 5 dtype: int64
3 6
dtype: int64
Namun, kita dapat menggunakan lebih dari nilai skalar dalam keysargumen untuk membuat argumen yang lebih dalam MultiIndex. Di sini kita melewati tuplespanjang 2 prepend dua tingkat baru dari a MultiIndex:
pd.concat(
[s1, s2, s3],
keys=[('A', 'X'), ('A', 'Y'), ('B', 'X')])
-----------------------------------------------
A X 2 1
3 2
Y 1 3
2 4
B X 1 5
3 6
dtype: int64
axis=1
Ini sedikit berbeda saat memperluas kolom. Ketika kami menggunakan axis=0(lihat di atas) kami keysbertindak sebagai MultiIndexlevel di samping indeks yang ada. Sebab axis=1, kita mengacu pada sumbu yang Seriestidak dimiliki objek, yaitu columnsatribut.
Variasi Dua
Seriesdengan
axis=1
Perhatikan bahwa penamaan s1dan s2masalah selama tidak keysdilewatkan, tetapi akan diganti jika keysdilewatkan.
| | | pd.concat(
| pd.concat( | pd.concat( | [s1.rename('U'),
pd.concat( | [s1, s2], | [s1.rename('U'), | s2.rename('V')],
[s1, s2], | axis=1, | s2.rename('V')], | axis=1,
axis=1) | keys=['X', 'Y']) | axis=1) | keys=['X', 'Y'])
-------------- | --------------------- | ---------------------- | ----------------------
0 1 | X Y | U V | X Y
1 NaN 3.0 | 1 NaN 3.0 | 1 NaN 3.0 | 1 NaN 3.0
2 1.0 4.0 | 2 1.0 4.0 | 2 1.0 4.0 | 2 1.0 4.0
3 2.0 NaN | 3 2.0 NaN | 3 2.0 NaN | 3 2.0 NaN
MultiIndexdengan
Seriesdan
axis=1
pd.concat(
[s1, s2],
axis=1,
keys=[('W', 'X'), ('W', 'Y')])
-----------------------------------
W
X Y
1 NaN 3.0
2 1.0 4.0
3 2.0 NaN
Dua
DataFramedengan
axis=1
Seperti pada axis=0contoh, keystambahkan level ke a MultiIndex, tapi kali ini ke objek yang disimpan di columnsatribut.
pd.concat( | pd.concat(
[d1, d2], | [d1, d2],
axis=1, | axis=1,
keys=['X', 'Y']) | keys=[('First', 'X'), ('Second', 'X')])
------------------------------- | --------------------------------------------
X Y | First Second
A B C B C D | X X
1 NaN NaN NaN 0.4 0.5 0.6 | A B C B C D
2 0.1 0.2 0.3 0.4 0.5 0.6 | 1 NaN NaN NaN 0.4 0.5 0.6
3 0.1 0.2 0.3 NaN NaN NaN | 2 0.1 0.2 0.3 0.4 0.5 0.6
| 3 0.1 0.2 0.3 NaN NaN NaN
Seriesdan
DataFramedengan
axis=1
Ini rumit. Dalam kasus ini, nilai kunci skalar tidak dapat bertindak sebagai satu-satunya tingkat indeks untuk Seriesobjek ketika menjadi kolom sementara juga bertindak sebagai tingkat pertama a MultiIndexuntuk DataFrame. Jadi Pandas akan kembali menggunakan nameatribut Seriesobjek sebagai sumber nama kolom.
pd.concat( | pd.concat(
[s1, d1], | [s1.rename('Z'), d1],
axis=1, | axis=1,
keys=['X', 'Y']) | keys=['X', 'Y'])
--------------------- | --------------------------
X Y | X Y
0 A B C | Z A B C
2 1 0.1 0.2 0.3 | 2 1 0.1 0.2 0.3
3 2 0.1 0.2 0.3 | 3 2 0.1 0.2 0.3
Batasan
keysdan
MultiIndexkesimpulan.
Pandas hanya tampaknya menyimpulkan nama kolom dari Seriesnama, tetapi tidak akan mengisi kekosongan saat melakukan penggabungan analog antara bingkai data dengan jumlah level kolom yang berbeda.
d1_ = pd.concat(
[d1], axis=1,
keys=['One'])
d1_
One
A B C
2 0.1 0.2 0.3
3 0.1 0.2 0.3
Kemudian gabungkan ini dengan bingkai data lain dengan hanya satu tingkat di objek kolom dan Pandas akan menolak untuk mencoba dan membuat tupel MultiIndexobjek dan menggabungkan semua bingkai data seolah-olah satu tingkat objek, skalar, dan tupel.
pd.concat([d1_, d2], axis=1)
(One, A) (One, B) (One, C) B C D
1 NaN NaN NaN 0.4 0.5 0.6
2 0.1 0.2 0.3 0.4 0.5 0.6
3 0.1 0.2 0.3 NaN NaN NaN
Mengoper dictbukan alist
Saat mengoper kamus, pandas.concatakan menggunakan kunci dari kamus sebagai keysparameter.
pd.concat( | pd.concat(
{0: d1, 1: d2}) | {0: d1, 1: d2}, axis=1)
----------------------- | -------------------------------
A B C D | 0 1
0 2 0.1 0.2 0.3 NaN | A B C B C D
3 0.1 0.2 0.3 NaN | 1 NaN NaN NaN 0.4 0.5 0.6
1 1 NaN 0.4 0.5 0.6 | 2 0.1 0.2 0.3 0.4 0.5 0.6
2 NaN 0.4 0.5 0.6 | 3 0.1 0.2 0.3 NaN NaN NaN
levels
Ini digunakan bersama dengan keysargumen. Saat levelsdibiarkan sebagai nilai defaultnya None, Pandas akan mengambil nilai unik dari setiap level yang dihasilkan MultiIndexdan menggunakannya sebagai objek yang digunakan dalam index.levelsatribut yang dihasilkan .
level : daftar urutan, default Tidak ada
Level spesifik (nilai unik) yang digunakan untuk membangun MultiIndex. Jika tidak, mereka akan disimpulkan dari kunci.
Jika Panda sudah menyimpulkan berapa level yang seharusnya, apa keuntungan yang ada untuk menentukannya sendiri? Saya akan menunjukkan satu contoh dan menyerahkan kepada Anda untuk memikirkan alasan lain mengapa ini mungkin berguna.
Contoh
Menurut dokumentasi, levelsargumennya adalah daftar urutan. Ini berarti kita dapat menggunakan yang lain pandas.Indexsebagai salah satu urutan tersebut.
Pertimbangkan bingkai data dfyang merupakan rangkaian dari d1, d2dan d3:
df = pd.concat(
[d1, d2, d3], axis=1,
keys=['First', 'Second', 'Fourth'])
df
First Second Fourth
A B C B C D A B D
1 NaN NaN NaN 0.4 0.5 0.6 0.7 0.8 0.9
2 0.1 0.2 0.3 0.4 0.5 0.6 NaN NaN NaN
3 0.1 0.2 0.3 NaN NaN NaN 0.7 0.8 0.9
Tingkatan dari objek kolom adalah:
print(df, *df.columns.levels, sep='\n')
Index(['First', 'Second', 'Fourth'], dtype='object')
Index(['A', 'B', 'C', 'D'], dtype='object')
Jika kita menggunakan sumdalam groupbykita dapatkan:
df.groupby(axis=1, level=0).sum()
First Fourth Second
1 0.0 2.4 1.5
2 0.6 0.0 1.5
3 0.6 2.4 0.0
Tetapi bagaimana jika bukannya ['First', 'Second', 'Fourth']ada kategori lain yang hilang bernama Thirddan Fifth? Dan saya ingin mereka dimasukkan dalam hasil groupbyagregasi? Kami dapat melakukan ini jika kami memiliki file pandas.CategoricalIndex. Dan kita dapat menentukannya sebelumnya dengan levelsargumen.
Jadi, mari kita definisikan dfsebagai:
cats = ['First', 'Second', 'Third', 'Fourth', 'Fifth']
lvl = pd.CategoricalIndex(cats, categories=cats, ordered=True)
df = pd.concat(
[d1, d2, d3], axis=1,
keys=['First', 'Second', 'Fourth'],
levels=[lvl]
)
df
First Fourth Second
1 0.0 2.4 1.5
2 0.6 0.0 1.5
3 0.6 2.4 0.0
Tapi level pertama dari objek kolom adalah:
df.columns.levels[0]
CategoricalIndex(
['First', 'Second', 'Third', 'Fourth', 'Fifth'],
categories=['First', 'Second', 'Third', 'Fourth', 'Fifth'],
ordered=True, dtype='category')
Dan groupbypenjumlahan kami terlihat seperti:
df.groupby(axis=1, level=0).sum()
First Second Third Fourth Fifth
1 0.0 1.5 0.0 2.4 0.0
2 0.6 1.5 0.0 0.0 0.0
3 0.6 0.0 0.0 2.4 0.0
names
Ini digunakan untuk memberi nama level yang dihasilkan MultiIndex. Panjang namesdaftar harus sesuai dengan jumlah level yang dihasilkan MultiIndex.
names : list, default None
Names untuk tingkat dalam indeks hierarki yang dihasilkan
pd.concat( | pd.concat(
[d1, d2], | [d1, d2],
keys=[0, 1], | axis=1, keys=[0, 1],
names=['lvl0', 'lvl1']) | names=['lvl0', 'lvl1'])
----------------------------- | ----------------------------------
A B C D | lvl0 0 1
lvl0 lvl1 | lvl1 A B C B C D
0 2 0.1 0.2 0.3 NaN | 1 NaN NaN NaN 0.4 0.5 0.6
3 0.1 0.2 0.3 NaN | 2 0.1 0.2 0.3 0.4 0.5 0.6
1 1 NaN 0.4 0.5 0.6 | 3 0.1 0.2 0.3 NaN NaN NaN
2 NaN 0.4 0.5 0.6 |
verify_integrity
Dokumentasi yang cukup jelas
verifikasi_integrity : boolean, default Salah
Periksa apakah sumbu gabungan baru berisi duplikat. Ini bisa sangat mahal dibandingkan dengan penggabungan data yang sebenarnya.
Karena indeks yang dihasilkan dari penggabungan d1dan d2tidak unik, pemeriksaan integritas akan gagal.
pd.concat([d1, d2])
A B C D
2 0.1 0.2 0.3 NaN
3 0.1 0.2 0.3 NaN
1 NaN 0.4 0.5 0.6
2 NaN 0.4 0.5 0.6
Dan
pd.concat([d1, d2], verify_integrity=True)
> ValueError: Indeks memiliki nilai yang tumpang tindih: [2]