Saat memilih satu kolom dari DataFrame pandas (katakanlah df.iloc[:, 0]
,, df['A']
atau df.A
, dll), vektor yang dihasilkan secara otomatis dikonversi ke Seri, bukan ke DataFrame kolom tunggal. Namun, saya menulis beberapa fungsi yang menggunakan DataFrame sebagai argumen input. Oleh karena itu, saya lebih suka berurusan dengan DataFrame kolom tunggal daripada Seri sehingga fungsinya dapat mengasumsikan bahwa df.columns dapat diakses. Sekarang saya harus secara eksplisit mengubah Seri menjadi DataFrame dengan menggunakan sesuatu seperti pd.DataFrame(df.iloc[:, 0])
. Ini sepertinya bukan metode yang paling bersih. Apakah ada cara yang lebih elegan untuk mengindeks dari DataFrame secara langsung sehingga hasilnya adalah DataFrame kolom tunggal dan bukan Seri?
92
Jawaban:
Seperti yang disebutkan @Jeff, ada beberapa cara untuk melakukan ini, tetapi saya merekomendasikan penggunaan loc / iloc agar lebih eksplisit (dan meningkatkan kesalahan lebih awal jika Anda mencoba sesuatu yang ambigu):
In [10]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B']) In [11]: df Out[11]: A B 0 1 2 1 3 4 In [12]: df[['A']] In [13]: df[[0]] In [14]: df.loc[:, ['A']] In [15]: df.iloc[:, [0]] Out[12-15]: # they all return the same thing: A 0 1 1 3
Dua pilihan terakhir menghilangkan ambiguitas dalam kasus nama kolom integer (tepatnya mengapa loc / iloc dibuat). Sebagai contoh:
In [16]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 0]) In [17]: df Out[17]: A 0 0 1 2 1 3 4 In [18]: df[[0]] # ambiguous Out[18]: A 0 1 1 3
sumber
[]
membuat hasilnya menjadiDataFrame
aSeries
, tetapi di mana dalam dokumen pandas apakah sintaks pengindeksan semacam ini dibahas? Saya hanya mencoba mendapatkan nama "resmi" untuk teknik pengindeksan ini sehingga saya benar-benar memahaminya. Terima kasih!Seperti yang direkomendasikan Andy Hayden , menggunakan .iloc / .loc untuk mengindeks kerangka data (kolom tunggal) adalah cara yang tepat; Hal lain yang perlu diperhatikan adalah bagaimana mengekspresikan posisi indeks. Gunakan label / posisi Indeks yang terdaftar sambil menentukan nilai argumen untuk diindeks sebagai Dataframe; kegagalan untuk melakukannya akan mengembalikan 'pandas.core.series.Series'
Memasukkan:
A_1 = train_data.loc[:,'Fraudster'] print('A_1 is of type', type(A_1)) A_2 = train_data.loc[:, ['Fraudster']] print('A_2 is of type', type(A_2)) A_3 = train_data.iloc[:,12] print('A_3 is of type', type(A_3)) A_4 = train_data.iloc[:,[12]] print('A_4 is of type', type(A_4))
Keluaran:
A_1 is of type <class 'pandas.core.series.Series'> A_2 is of type <class 'pandas.core.frame.DataFrame'> A_3 is of type <class 'pandas.core.series.Series'> A_4 is of type <class 'pandas.core.frame.DataFrame'>
sumber
Anda dapat menggunakan
df.iloc[:, 0:1]
, dalam hal ini vektor yang dihasilkan adalah aDataFrame
dan bukan seri.Seperti yang Anda lihat:
sumber
Ketiga pendekatan ini telah disebutkan:
pd.DataFrame(df.loc[:, 'A']) # Approach of the original post df.loc[:,[['A']] # Approach 2 (note: use iloc for positional indexing) df[['A']] # Approach 3
pd.Series.to_frame () adalah pendekatan lain.
Karena ini adalah metode, ini dapat digunakan dalam situasi di mana pendekatan kedua dan ketiga di atas tidak berlaku. Secara khusus, ini berguna saat menerapkan beberapa metode ke kolom dalam kerangka data Anda dan Anda ingin mengonversi keluaran menjadi kerangka data, bukan rangkaian. Misalnya, dalam Notebook Jupyter, rangkaian tidak akan memiliki keluaran yang bagus, tetapi kerangka data akan.
# Basic use case: df['A'].to_frame() # Use case 2 (this will give you pretty output in a Jupyter Notebook): df['A'].describe().to_frame() # Use case 3: df['A'].str.strip().to_frame() # Use case 4: def some_function(num): ... df['A'].apply(some_function).to_frame()
sumber