Pandas 데이터 프레임 열 dtypes 할당


110

dtype에서 여러 열의 s 를 설정하고 싶습니다 pd.Dataframe(파일이 수정되지 않았기 때문에 목록 목록으로 수동으로 구문 분석해야하는 파일이 있습니다 pd.read_csv).

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

나는 얻다

ValueError: entry not a 2- or 3- tuple

내가 설정할 수있는 유일한 방법은 각 열 변수를 반복하고 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

더 좋은 방법이 있습니까?


이것은 아마도 좋은의 것 버그 / 기능 요청 ... 현재 내가 (당신이 스칼라 전달할 수 있지만 엄격한 아니다) 확인 DTYPE 인수가 무엇을하고 있는지 아니에요
앤디 헤이든

2
참고 : df = pd.DataFrame([['a','1'],['b','2']], dtype='int', columns=['x','y'])"작품":하지만 ...의
앤디 헤이든

1
예, 실제로 "작동"합니다. 예상치 못한 ...
hatmatrix

답변:


65

0.17부터 명시 적 변환을 사용해야합니다.

pd.to_datetime, pd.to_timedelta and pd.to_numeric

(아래에서 언급했듯이 더 이상 "마법" convert_objects은 0.17에서 더 이상 사용되지 않습니다.)

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

변환하려는 각 열에 적용 할 수 있습니다.

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

dtype이 업데이트되었는지 확인합니다.


pandas convert_objects0.12-0.16에 대한 이전 / 사용 중단 된 답변 : 더 나은 dtype을 추론 하는 데 사용할 수 있습니다 .

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

마법! (사용되지 않는 것을보고 슬프다.)


2
type.convertR 에서처럼 약간; 좋지만 어떤 경우에는 명시적인 사양을 바라는 사람이 남습니다.
hatmatrix

1
문자열이어야하지만 정수로 변환 할 수있는 값이 하나 이상 포함 된 열이있는 경우주의하십시오. 그것을 가지고가는 것은 하나 개의 값이며, 전체 필드는 float64로 변환됩니다
마이클 데이비드 왓슨

18
convert_objects()더 이상 사용되지 않는 것으로 나타났습니다 ... 무엇을 대체했는지 모르겠습니까?
joefromct

6
객체의 열에 대한 재 추론 데이터 dtypes를 사용 DataFrame.infer_objects에 ()
제임스 토빈

1
@smci 좋아, 나는 편집했다. 더 이상 사용되지 않는 답변이 많이 있습니다. 모두 찾을 수있는 방법을 찾아야합니다.
Andy Hayden

62

저와 같은 Google (등)에서 오는 사람들을 위해 :

convert_objects 0.17부터 사용되지 않습니다. 사용하면 다음과 같은 경고가 표시됩니다.

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

다음과 같이해야합니다.


pd.to_datetime, to_timedelta, to_numeric이것의 몇 가지 예를 던지면 받아 들여진 대답이 될 것입니다.
smci

41

pandas를 사용 DataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs)하여 명시 적으로 유형을 설정하고 원하는 dtypes로 사전에 전달할 수 있습니다.dtype

여기에 예가 있습니다.

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

이제 변경된 것을 볼 수 있습니다.

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

13

열 유형을 설정하는 또 다른 방법은 먼저 원하는 유형으로 numpy 레코드 배열을 생성하고이를 채운 다음 DataFrame 생성자에 전달하는 것입니다.

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

비슷한 문제에 직면 해 있습니다. 제 경우에는 수동으로 구문 분석해야하는 시스코 로그의 1000 개의 파일이 있습니다.

필드와 유형을 유연하게 사용하기 위해 실제로 dtype 사양에 대한 사전을 허용하는 StringIO + read_cvs를 사용하여 성공적으로 테스트했습니다.

일반적으로 각 파일 (5k-20k 줄)을 버퍼에 넣고 dtype 사전을 동적으로 만듭니다.

결국 나는 이러한 데이터 프레임을 hdf5에 덤프하는 큰 데이터 프레임으로 연결합니다 (범주 형 ... 0.19 덕분에).

이 라인을 따라 뭔가

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

별로 비단뱀 같지는 않지만 ....

도움이되기를 바랍니다.

JC


0

형식화 된 np.arrays를 사용한 다음 데이터 및 열 이름을 사전으로 전달하는 것이 좋습니다.

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,
   }
 )
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.