Saya sangat bingung dengan metode pengindeksan yang berbeda menggunakan iloc
di panda.
Katakanlah saya sedang mencoba mengubah 1-d Dataframe menjadi 2-d Dataframe. Pertama saya memiliki Dataframe 1-d berikut
a_array = [1,2,3,4,5,6,7,8]
a_df = pd.DataFrame(a_array).T
Dan saya akan mengubahnya menjadi 2-d Dataframe dengan ukuran 2x4
. Saya mulai dengan menetapkan 2-d Dataframe sebagai berikut:
b_df = pd.DataFrame(columns=range(4),index=range(2))
Kemudian saya menggunakan for-loop untuk membantu saya mengkonversi a_df
(1-d) ke b_df
(2-d) dengan kode berikut
for i in range(2):
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
Itu hanya memberi saya hasil berikut
0 1 2 3
0 1 2 3 4
1 NaN NaN NaN NaN
Tetapi ketika saya berubah b_df.iloc[i,:]
menjadi b_df.iloc[i][:]
. Hasilnya benar seperti berikut, yang saya inginkan
0 1 2 3
0 1 2 3 4
1 5 6 7 8
Adakah yang bisa menjelaskan kepada saya apa perbedaan antara .iloc[i,:]
dan .iloc[i][:]
adalah, dan mengapa .iloc[i][:]
bekerja dalam contoh saya di atas tetapi tidak.iloc[i,:]
b_df.iloc[1] = a_df.iloc[0, 4:8]
menetapkan seri dengan indeks[4, 5, 6, 7]
ke seri dengan indeks[0, 1, 2, 3]
. Tidak ada tumpang tindih jadiNaN
ditugaskan untuk semua elemen. Sampai pada titik ini masuk akal bagi saya. Tetapi seperti Anda, saya tidak jelas mengapab_df.iloc[1][:] = ...
berperilaku berbeda — memeriksa objekb_df.iloc[1]
danb_df.iloc[1][:]
tidak menunjukkan perbedaan di antara indeks. Tebakan terbaik saya adalah bahwa menetapkan langsung ke salinan ([:]
) diperlakukan sebagai kasus khusus oleh Pandas yang membuatnya mengabaikan indeks penerima dan membuat perbedaan ini.Jawaban:
Ada perbedaan yang sangat, sangat besar antara
series.iloc[:]
danseries[:]
, ketika menetapkan kembali.(i)loc
selalu periksa untuk memastikan apa pun yang Anda tetapkan cocok dengan indeks penerima yang ditunjuk. Sementara itu,[:]
sintaks menetapkan untuk array NumPy yang mendasarinya, melewati indeks alignmentSekarang setelah Anda memahami perbedaannya, mari kita lihat apa yang terjadi dalam kode Anda. Cukup cetak RHS loop Anda untuk melihat apa yang Anda tetapkan:
Saat menetapkan
b_df.iloc[i, :]
dalam iterasi kedua, indeks berbeda sehingga tidak ada yang ditetapkan dan Anda hanya melihat NaNs. Namun, mengubahb_df.iloc[i, :]
keb_df.iloc[i][:]
berarti Anda menetapkan ke array NumPy yang mendasarinya, sehingga perataan indeks dilewati. Operasi ini lebih baik dinyatakan sebagaiPerlu juga disebutkan bahwa ini adalah bentuk penugasan berantai, yang bukan merupakan hal yang baik , dan juga membuat kode Anda lebih sulit dibaca dan dipahami.
sumber
[:]
sintaks yang diberikan ke array NumPy yang mendasarinya"?Perbedaannya adalah bahwa dalam kasus pertama interpreter Python mengeksekusi kode sebagai:
di mana nilainya akan menjadi sisi kanan persamaan. Sedangkan dalam kasus kedua interpreter Python mengeksekusi kode sebagai:
di mana lagi nilainya akan menjadi sisi kanan persamaan.
Dalam masing-masing dua kasus metode yang berbeda akan disebut di dalam setitem karena perbedaan kunci (i, slice (None)) dan slice (None) Oleh karena itu kami memiliki perilaku yang berbeda.
sumber
b_df.iloc[i]
danb_df.iloc[i][:]
memiliki indeks yang sama. Mengapa Anda dapat menetapkan seri dengan indeks tidak cocok untuk satu tetapi tidak yang lain?Perbedaan antara
.iloc[i,:]
dan.iloc[i][:]
Dalam kasus
.iloc[i,:]
Anda mengakses langsung ke kepemilikan tertentuDataFrame
, dengan memilih semua (:
) kolomi
baris ke - th. Sejauh yang saya tahu, itu setara dengan membiarkan dimensi ke-2 tidak ditentukan (.iloc[i]
).Jika
.iloc[i][:]
Anda sedang melakukan 2 operasi berantai. Jadi, hasilnya.iloc[i]
nanti akan terpengaruh oleh[:]
. Menggunakan ini untuk menetapkan nilai tidak disarankan oleh Pandas sendiri di sini dengan peringatan, jadi Anda tidak boleh menggunakannya:Seperti @Scott disebutkan pada komentar OP, penyelarasan data adalah intrinsik , sehingga indeks di sisi kanan
=
tidak akan dimasukkan jika mereka tidak ada di sisi kiri. Inilah sebabnya mengapa adaNaN
nilai di baris ke-2.Jadi, untuk memperjelas, Anda bisa melakukan hal berikut:
Atau Anda dapat mengonversi ke
list
alih-alih menggunakanreset_index
:sumber