Pandas veri çerçevesi sütun d türlerini atayın


111

dtypeBirden çok sütunun 'sini' içinde ayarlamak istiyorum pd.Dataframe(dosya uygun olmadığı için bir liste listesine manuel olarak ayrıştırmam gereken bir dosyam var pd.read_csv)

import pandas as pd
print pd.DataFrame([['a','1'],['b','2']],
                   dtype={'x':'object','y':'int'},
                   columns=['x','y'])

alırım

ValueError: entry not a 2- or 3- tuple

Bunları ayarlayabilmemin tek yolu, her bir sütun değişkeni üzerinden döngü yapmak ve ile yeniden biçimlendirmektir astype.

dtypes = {'x':'object','y':'int'}
mydata = pd.DataFrame([['a','1'],['b','2']],
                      columns=['x','y'])
for c in mydata.columns:
    mydata[c] = mydata[c].astype(dtypes[c])
print mydata['y'].dtype   #=> int64

Daha iyi bir yol var mı?


Bu belki de iyi bir hata / özellik isteği olabilir , şu anda dtype argümanının ne yaptığından emin değilim (skaler olarak iletebilirsiniz, ancak katı değildir) ...
Andy Hayden

2
Bilginize: df = pd.DataFrame([['a','1'],['b','2']], dtype='int', columns=['x','y'])"çalışıyor" ... ama: s
Andy Hayden

1
Evet, gerçekten "işe yarıyor"; tahmin edilemez ...
hatmatrix

Bu GitHub sorunu yakında alakalı hale gelebilir: github.com/pydata/pandas/issues/9287
Amelio Vazquez-Reina

Yanıtlar:


65

0.17'den beri, açık dönüşümleri kullanmanız gerekir:

pd.to_datetime, pd.to_timedelta and pd.to_numeric

(Aşağıda belirtildiği gibi, artık "sihir" convert_objects0.17'de kullanımdan kaldırılmadı)

df = pd.DataFrame({'x': {0: 'a', 1: 'b'}, 'y': {0: '1', 1: '2'}, 'z': {0: '2018-05-01', 1: '2018-05-02'}})

df.dtypes

x    object
y    object
z    object
dtype: object

df

   x  y           z
0  a  1  2018-05-01
1  b  2  2018-05-02

Bunları dönüştürmek istediğiniz her bir sütuna uygulayabilirsiniz:

df["y"] = pd.to_numeric(df["y"])
df["z"] = pd.to_datetime(df["z"])    
df

   x  y          z
0  a  1 2018-05-01
1  b  2 2018-05-02

df.dtypes

x            object
y             int64
z    datetime64[ns]
dtype: object

ve dtype'ın güncellendiğini onaylayın.


Pandalar için ESKİ / KULLANIMDAN KALDIRILMIŞ CEVAP 0.12 - 0.16: Daha convert_objectsiyi dtipler çıkarmak için kullanabilirsiniz :

In [21]: df
Out[21]: 
   x  y
0  a  1
1  b  2

In [22]: df.dtypes
Out[22]: 
x    object
y    object
dtype: object

In [23]: df.convert_objects(convert_numeric=True)
Out[23]: 
   x  y
0  a  1
1  b  2

In [24]: df.convert_objects(convert_numeric=True).dtypes
Out[24]: 
x    object
y     int64
dtype: object

Büyü! (Kullanımdan kaldırıldığını görmek üzücü.)


2
type.convertR'deki gibi biraz; güzel, ancak bazı durumlarda açık spesifikasyonlar isteyen birini bırakır.
hatmatrix

1
Dize olması gereken ancak int'e dönüştürülebilecek en az bir değer içeren bir sütununuz varsa dikkatli olun. Tek gereken bir değerdir ve tüm alan float64'e dönüştürülür
Michael David Watson

18
Kullanımdan convert_objects()kaldırıldığını fark ettim ... onun yerini neyin aldığından emin değilim?
joefromct

6
Nesne sütunları için veri türlerini yeniden çıkarmak için DataFrame.infer_objects () kullanın
James Tobin

1
@smci tamam, düzenledim. Kullanımdan kaldırılan bir sürü cevap var, hepsini bulmanın bir yolunu bulmalıyım.
Andy Hayden

62

Benim gibi Google'dan (vb.) Gelenler için:

convert_objects 0.17'den beri kullanımdan kaldırıldı - kullanırsanız şuna benzer bir uyarı alırsınız:

FutureWarning: convert_objects is deprecated.  Use the data-type specific converters 
pd.to_datetime, pd.to_timedelta and pd.to_numeric.

Aşağıdaki gibi bir şey yapmalısınız:


Bazı örneklerde attıysanız pd.to_datetime, to_timedelta, to_numericbunun kabul edilen cevap olması gerekir.
smci

41

türleri açıkça pandalarla ayarlayabilir ve DataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs)istediğiniz dtype'lerle bir sözlüğe geçebilirsiniz.dtype

işte bir örnek:

import pandas as pd
wheel_number = 5
car_name = 'jeep'
minutes_spent = 4.5

# set the columns
data_columns = ['wheel_number', 'car_name', 'minutes_spent']

# create an empty dataframe
data_df = pd.DataFrame(columns = data_columns)
df_temp = pd.DataFrame([[wheel_number, car_name, minutes_spent]],columns = data_columns)
data_df = data_df.append(df_temp, ignore_index=True) 

In [11]: data_df.dtypes
Out[11]:
wheel_number     float64
car_name          object
minutes_spent    float64
dtype: object

data_df = data_df.astype(dtype= {"wheel_number":"int64",
        "car_name":"object","minutes_spent":"float64"})

şimdi bunun değiştiğini görebilirsin

In [18]: data_df.dtypes
Out[18]:
wheel_number       int64
car_name          object
minutes_spent    float64

13

Sütun türlerini ayarlamanın başka bir yolu, önce istediğiniz türlerle bir numpy kayıt dizisi oluşturmak, bunu doldurmak ve ardından bunu bir DataFrame yapıcısına iletmektir.

import pandas as pd
import numpy as np    

x = np.empty((10,), dtype=[('x', np.uint8), ('y', np.float64)])
df = pd.DataFrame(x)

df.dtypes ->

x      uint8
y    float64

0

size benzer bir problemle karşı karşıya. Benim durumumda, manuel olarak ayrıştırmam gereken cisco günlüklerinden 1000'lerce dosya var.

Alanlar ve türler konusunda esnek olabilmek için StringIO + read_cvs kullanarak başarıyla test ettim, bu gerçekten de dtype belirtimi için bir emir kabul ediyor.

Genellikle dosyaların her birini (5k-20k satırları) bir arabelleğe alıp dinamik olarak dtype sözlükleri oluşturuyorum.

Sonunda (kategorik olarak ... 0.19 sayesinde) bu veri çerçevelerini hdf5'e döktüğüm büyük bir veri çerçevesine birleştirdim.

Bu çizgiler boyunca bir şey

import pandas as pd
import io 

output = io.StringIO()
output.write('A,1,20,31\n')
output.write('B,2,21,32\n')
output.write('C,3,22,33\n')
output.write('D,4,23,34\n')

output.seek(0)


df=pd.read_csv(output, header=None,
        names=["A","B","C","D"],
        dtype={"A":"category","B":"float32","C":"int32","D":"float64"},
        sep=","
       )

df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 4 columns):
A    5 non-null category
B    5 non-null float32
C    5 non-null int32
D    5 non-null float64
dtypes: category(1), float32(1), float64(1), int32(1)
memory usage: 205.0 bytes
None

Pek pitonik değil .... ama iş yapıyor

Umarım yardımcı olur.

JC


0

Yazılı np.arrays kullanmanız daha iyi olur ve ardından verileri ve sütun adlarını sözlük olarak iletin.

import numpy as np
import pandas as pd
# Feature: np arrays are 1: efficient, 2: can be pre-sized
x = np.array(['a', 'b'], dtype=object)
y = np.array([ 1 ,  2 ], dtype=np.int32)
df = pd.DataFrame({
   'x' : x,    # Feature: column name is near data array
   'y' : y,
   }
 )
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.