DataFrame'deki dizeler, ancak dtype nesnedir


101

Pandalar neden bana nesnelerim olduğunu söylüyor, ancak seçili sütundaki her öğe bir dizedir - açık dönüştürmeden sonra bile.

Bu benim DataFrame'im:

<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)

Beş tanesi dtype object. Bu nesneleri açıkça dizelere dönüştürüyorum:

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

Sonra, df["attr2"]hala var dtype objectolmasına rağmen, type(df["attr2"].ix[0]ortaya strdoğru olan.

Pandalar, int64ve float64ve arasında ayrım yapar object. Hayır olmadığında arkasındaki mantık nedir dtype str? Neden strkapsam dahilindedir object?


Buraya geldi çünkü birleştirmeler, her "eşit" dizesi olmasına rağmen "nesne türü" nedeniyle başarısız oluyor
Monica Heddneck

Yanıtlar:


149

Dtype nesnesi NumPy'den gelir, bir ndarray'deki öğenin türünü tanımlar. Bir ndarray'deki her eleman bayt olarak aynı boyuta sahip olmalıdır. İnt64 ve float64 için bunlar 8 bayttır. Ancak dizeler için dizenin uzunluğu sabit değildir. Dolayısıyla, pandalar dizelerin baytlarını doğrudan ndarray'e kaydetmek yerine, ndarray nesnesini kullanır, bu da nesnelere işaretçileri kaydeder, bu nedenle bu tür dtype ndarray nesnedir.

İşte bir örnek:

  • int64 dizisi 4 int64 değeri içerir.
  • nesne dizisi, 3 dize nesnesine 4 işaretçi içerir.

görüntü açıklamasını buraya girin


4
Bununla birlikte, 'nesne' türü sütunlara sahip olmanın, DataFrame okuma / yazma işlemlerinin performansı üzerinde büyük bir etkiye sahip olduğunu unutmayın
erwanp

bir şekilde dize olarak döndürülen veri türünü alabilir miyim? Her zaman type (df ["column"]. İloc [0]) kullanabileceğimi biliyorum, ancak bu öyle olabilir ki nan
user1953366

9

@ HYRY'nin cevabı harika. Sadece biraz daha içerik sağlamak istiyorum ..

Diziler , verileri bitişik , sabit boyutlu bellek blokları olarak depolar . Bu özelliklerin bir araya gelmesi, dizileri veri erişimi için ışık hızında yapan şeydir. Örneğin, bilgisayarınızın 32 bitlik bir tamsayı dizisini nasıl depolayabileceğini düşünün [3,0,1].

görüntü açıklamasını buraya girin

Bilgisayarınızdan dizideki 3. öğeyi getirmesini isterseniz, başlangıçta başlayacak ve ardından 3. öğeye ulaşmak için 64 bit boyunca atlayacaktır. Tam olarak kaç bit atlanacağını bilmek dizileri hızlı yapan şeydir .

Şimdi dizelerin sırasını düşünün ['hello', 'i', 'am', 'a', 'banana']. Dizeler, boyutları değişen nesnelerdir, bu nedenle onları bitişik bellek bloklarında saklamaya çalışırsanız, sonuç böyle görünür.

görüntü açıklamasını buraya girin

Artık bilgisayarınız, rastgele istenen bir öğeye erişmek için hızlı bir yola sahip değil. Bunun üstesinden gelmenin anahtarı işaretçiler kullanmaktır. Temel olarak, her dizeyi rastgele bir bellek konumunda saklayın ve diziyi her dizenin bellek adresiyle doldurun. (Bellek adresleri yalnızca tam sayılardır.) Yani şimdi işler şöyle gözüküyor

görüntü açıklamasını buraya girin

Şimdi, bilgisayarınızdan 3. elemanı almasını isterseniz, tıpkı daha önce olduğu gibi, 64 bit üzerinden atlayabilir (bellek adreslerinin 32 bitlik tam sayılar olduğu varsayılırsa) ve ardından dizgiyi almak için fazladan bir adım atabilir.

NumPy için zorluk, işaretçilerin gerçekte dizeleri işaret ettiğinin garantisinin olmamasıdır. Bu yüzden dtype'ı 'nesne' olarak rapor eder.

Utanmazca, bunu başlangıçta tartıştığım kendi blog makalemi ekleyeceğim .


Güzel yazılmış ..
Teşekkürler

7

Kabul edilen cevap güzel. Belgelere atıfta bulunan bir cevap vermek istedim . Belgeler şunu söylüyor:

Pandalar, dizeleri depolamak için nesne dtype'yi kullanır.

Önde gelen yorumun dediği gibi "Endişelenmeyin; böyle olması gerekiyor." (Kabul edilen yanıt "neden" i açıklamakta harika bir iş çıkarsa da; dizeler değişken uzunluktadır)

Ancak dizeler için dizenin uzunluğu sabit değildir.


Neden geçtiğim her sütunu kabul etmesi için scipy'ye veya sklearn astype'a (str) dönüştürmem gerekiyor? Görünüşe göre bunu başlangıçta tüm sütunlara uygulayabilmeliyim.
Tinkinc

Anlamıyorum; Eğer @Tinkinc ne olur yok dizeye sütunları dönüştürmek? Ve bu cevap için tüm sütunları dönüştürmek için zarif bir şekilde görünüyorastype(str) ben hala merak dize dönüştürme gereklidir ediyorum rağmen
Kırmızı Bezelye

Veri çerçevemdeki tüm nesneleri (1,0) yerine (1, nan)
dolduramıyorum

Üzgünüm @ Tinkinc Hala anlamıyorum; Yardım etmek istiyorum, ancak sorununuz bir Stack Overflow yorumundan daha karmaşık görünüyor. Bir soru sormayı veya sohbette bana katılmayı düşünün. (sadece davet etti)
The Red Pea

2

1.0.0 (Ocak 2020) sürümünden itibaren, pandalar, üzerinden dize türleri için birinci sınıf destek sağlayan deneysel bir özellik olarak tanıtıldı pandas.StringDtype.

Hala görüyor olacağım ederken object, varsayılan olarak, yeni tip a belirterek kullanılabilir dtypeait pd.StringDtypeveya basitçe '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

2
Bunu kullanmayın .... henüz. Belirtildiği gibi, The implementation may change without warning.bu, yeni güncellemelerin eski programlarınızı bozacağı anlamına gelir.
NoName

1
Bu, onu ne için kullanacağına bağlı. Sürekli paket yükseltmelerinin gerekli olduğu ve API kırılmasının kabul edilemez bir bakım yüküne neden olduğu bir üretim sisteminde kullanmak istiyorsanız, emin olun, "deneysel" kelimesine çok dikkat edin, ancak keşif yapmak için pandalar kullanıyorsanız yaşam süresi bir iş gününü uzatmayan senaryolardaki analizler, o zaman bu endişeler sizin için çok az şey ifade etmelidir.
fuglede

1
Pandas 1.1'den itibaren, API stabilize edilmiş görünüyor Tüm dtype'lar artık StringDtype'a dönüştürülebilir .
D3f0
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.