String dalam DataFrame, tetapi dtype adalah objek

96

Mengapa Pandas memberi tahu saya bahwa saya memiliki objek, meskipun setiap item di kolom yang dipilih adalah string - bahkan setelah konversi eksplisit.

Ini adalah DataFrame saya:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 56992 entries, 0 to 56991
Data columns (total 7 columns):
id            56992  non-null values
attr1         56992  non-null values
attr2         56992  non-null values
attr3         56992  non-null values
attr4         56992  non-null values
attr5         56992  non-null values
attr6         56992  non-null values
dtypes: int64(2), object(5)

Lima di antaranya adalah dtype object. Saya secara eksplisit mengonversi objek-objek itu menjadi string:

for c in df.columns:
    if df[c].dtype == object:
        print "convert ", df[c].name, " to string"
        df[c] = df[c].astype(str)

Kemudian, df["attr2"]masih memiliki dtype object, meskipun type(df["attr2"].ix[0]mengungkapkan str, mana yang benar.

Panda membedakan antara int64dan float64dan object. Apa logika di baliknya bila tidak ada dtype str? Mengapa strdilindungi oleh object?

Xiphias
sumber
Datang ke sini karena gabungan gagal karena 'tipe objek' meskipun setiap string "adalah"
Monica Heddneck

Jawaban:

145

Objek dtype berasal dari NumPy, ini menjelaskan tipe elemen dalam ndarray. Setiap elemen dalam ndarray harus memiliki ukuran yang sama dalam byte. Untuk int64 dan float64, ukurannya 8 byte. Namun untuk senar, panjang senar tidak tetap. Jadi, alih-alih menyimpan byte string dalam ndarray secara langsung, Pandas menggunakan objek ndarray, yang menyimpan pointer ke objek, karena jenis ini ndarray adalah objek.

Berikut ini contohnya:

  • array int64 berisi 4 nilai int64.
  • array objek berisi 4 pointer ke 3 objek string.

masukkan deskripsi gambar di sini

HYRY
sumber
3
Namun perlu dicatat bahwa memiliki kolom tipe 'objek' memiliki dampak besar pada kinerja operasi baca / tulis
DataFrame
dapatkah saya mendapatkan tipe data yang dikembalikan sebagai string, entah bagaimana. Saya tahu saya selalu bisa menggunakan type (df ["column"]. Iloc [0]), tetapi mungkin saja ini adalah nan
user1953366
7

Jawaban yang diterima bagus. Hanya ingin memberikan jawaban yang mereferensikan dokumentasi . Dokumentasinya mengatakan:

Pandas menggunakan objek dtype untuk menyimpan string.

Seperti komentar utama mengatakan "Jangan khawatir tentang itu; seharusnya seperti ini." (Meskipun jawaban yang diterima melakukan pekerjaan yang baik dalam menjelaskan "mengapa"; string memiliki panjang variabel)

Namun untuk senar, panjang senar tidak tetap.

Kacang Merah
sumber
Mengapa saya perlu mengubah setiap kolom yang saya berikan menjadi scipy atau sklearn astype (str) agar dapat menerimanya? Sepertinya saya harus dapat menerapkannya ke semua kolom pada awalnya.
Tinkinc
Saya tidak mengerti; @Tinkinc apa yang terjadi jika Anda tidak mengubah kolom menjadi string? Dan jawaban ini tampaknya merupakan cara yang elegan untuk mengubah semua kolom menjadiastype(str) meskipun saya masih bertanya-tanya konversi string diperlukan
The Red Pea
Saya tidak bisa mengisi (0) semua objek dalam kerangka data saya tetap (1, nan) bukannya (1,0)
Tinkinc
Maaf @Tinkinc Saya masih tidak mengerti; Saya ingin membantu, tetapi masalah Anda terdengar lebih kompleks daripada komentar Stack Overflow. Pertimbangkan untuk mengajukan pertanyaan, atau bergabung dengan saya dalam obrolan. (baru saja mengundang Anda)
The Red Pea
5

@ HYRY Jawabannya bagus. Saya hanya ingin memberikan lebih banyak konteks ..

Array disimpan data yang berdekatan , berukuran tetap blok memori. Kombinasi properti ini bersama-sama membuat array menjadi secepat kilat untuk akses data. Misalnya, pertimbangkan bagaimana komputer Anda dapat menyimpan larik bilangan bulat 32-bit [3,0,1],.

masukkan deskripsi gambar di sini

Jika Anda meminta komputer Anda untuk mengambil elemen ke-3 dalam larik, itu akan dimulai dari awal dan kemudian melompati 64 bit untuk sampai ke elemen ke-3. Mengetahui dengan tepat berapa banyak bit untuk dilompati itulah yang membuat array menjadi cepat .

Sekarang perhatikan urutan string ['hello', 'i', 'am', 'a', 'banana']. String adalah objek yang ukurannya bervariasi, jadi jika Anda mencoba menyimpannya di blok memori yang berdekatan, hasilnya akan terlihat seperti ini.

masukkan deskripsi gambar di sini

Sekarang komputer Anda tidak memiliki cara cepat untuk mengakses elemen yang diminta secara acak. Kunci untuk mengatasi ini adalah dengan menggunakan petunjuk. Pada dasarnya, simpan setiap string di beberapa lokasi memori acak, dan isi array dengan alamat memori setiap string. (Alamat memori hanyalah bilangan bulat.) Jadi sekarang, semuanya terlihat seperti ini

masukkan deskripsi gambar di sini

Sekarang, jika Anda meminta komputer Anda untuk mengambil elemen ke-3, seperti sebelumnya, itu dapat melompati 64 bit (dengan asumsi alamat memori adalah bilangan bulat 32-bit) dan kemudian membuat satu langkah ekstra untuk mengambil string.

Tantangan bagi NumPy adalah tidak ada jaminan bahwa pointer benar-benar mengarah ke string. Itulah mengapa ini melaporkan tipe dtype sebagai 'object'.

Tanpa malu-malu akan pasang artikel blog saya sendiri tempat saya pertama kali membahas ini.

Ben
sumber
Ditulis dengan baik .. Terima kasih
tedd
1

Mulai versi 1.0.0 (Januari 2020), panda telah diperkenalkan sebagai fitur eksperimental yang menyediakan dukungan kelas satu untuk jenis string melalui pandas.StringDtype .

Meskipun Anda masih dapat melihat objectsecara default, tipe baru dapat digunakan dengan menentukan dtypedari pd.StringDtypeatau cukup 'string':

>>> pd.Series(['abc', None, 'def'])
0     abc
1    None
2     def
dtype: object
>>> pd.Series(['abc', None, 'def'], dtype=pd.StringDtype())
0     abc
1    <NA>
2     def
dtype: string
>>> pd.Series(['abc', None, 'def']).astype('string')
0     abc
1    <NA>
2     def
dtype: string
fuglede
sumber
2
Jangan gunakan ini .... dulu. Seperti yang mereka nyatakan, The implementation may change without warning.yang berarti pembaruan baru akan merusak program lama Anda.
NoName
1
Nah, itu semua tergantung pada apa Anda akan menggunakannya. Jika Anda ingin menggunakannya dalam sistem produksi yang memerlukan peningkatan paket berkelanjutan, dan saat kerusakan API menyebabkan beban pemeliharaan yang tidak dapat diterima, maka pastikan, perhatikan baik-baik kata "eksperimental", tetapi jika Anda menggunakan panda untuk melakukan eksplorasi menganalisis dalam skrip yang waktu hidupnya tidak menambah hari kerja, maka kekhawatiran itu seharusnya tidak berarti bagi Anda.
fuglede
Mulai Pandas 1.1, API tampaknya telah distabilkan. Semua dtype sekarang dapat dikonversi ke StringDtype .
D3f0