【跟著stackoverflow學Pandas】
阿新 • • 發佈:2019-02-08
最近做一個系列部落格,跟著stackoverflow學Pandas。
Pandas: change data type of columns - Pandas修改列的型別
資料集
import pandas as pd
a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['col1', 'col2', 'col3'])
print df.head()
# col1 col2 col3
# 0 a 1.2 4.2
# 1 b 70 0.03
# 2 x 5 0
print df.dtypes
# col1 object
# col2 object
# col3 object
# dtype: object
這裡的3列資料,col1是明顯的字元資料,col2、col3是數值型資料,但是因為資料在匯入時加了引號,按照字串資料來處理,如果我們想對他們進行數值操作,就需要進行轉換。
下面我們推薦幾種方法
pd.to_numeric
對於明顯是數值的資料,轉換型別直接採用 pd.to_numeric 就可以了,如果資料既有數值型又有字元型,那麼我們就要根據情況區別對待了。
s = pd.Series(['1' , '2', '4.7', 'pandas', '10'])
# pd.to_numeric(s) # 如果直接轉換會報錯
# ValueError: Unable to parse string "pandas" at position 3
# 可以強制轉換,字元型資料就會變成 NaN,資料型別變為 float64
pd.to_numeric(s, errors='coerce')
# 0 1.0
# 1 2.0
# 2 4.7
# 3 NaN
# 4 10.0
# dtype: float64
# 也可以忽略錯誤,結果不做處理
pd.to_numeric(s, errors='ignore' )
# 0 1
# 1 2
# 2 4.7
# 3 pandas
# 4 10
# dtype: object
如果有多個列需要轉換,可以採用apply進行批量操作。
df[['col2','col3']] = df[['col2','col3']].apply(pd.to_numeric, errors='ignore') # 同樣可以新增 errors 引數
print df
# col1 col2 col3
# 0 a 1.2 4.20
# 1 b 70.0 0.03
# 2 x 5.0 0.00
print df.dtypes
# col1 object
# col2 float64
# col3 float64
# dtype: object
相似的函式,還有 pd.to_datetime、pd.to_timedelta,可以實現對時間的轉換。
astype
pd.to_numeric 用起來很簡單,但是它把所有的變數都變成了float64,那麼如果資料是整形呢。我們可以試試 astype 函式。
a = [['a', '1', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
print df
# one two three
# 0 a 1 4.2
# 1 b 70 0.03
# 2 x 5 0
print df.dtypes
# one object
# two object
# three object
# dtype: object
# 批量操作
df[['two', 'three']] = df[['two', 'three']].astype(float)
print df.dtypes
# one object
# two float64
# three float64
# dtype: object
df['two'] = df['two'].astype(int)
print df.dtypes
# one object
# two int64
# three float64
# dtype: object
生成DataFrame時指定變數型別
df = pd.DataFrame(a, columns=['one', 'two', 'three'], dtype={'one': str, 'two': int, 'three': float})
infer_objects
如果資料很多無法判斷資料型別,可以採用 infer_objects(Pandas Version 0.21.0)
df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object')
df.dtypes
# a object
# b object
# dtype: object
df = df.infer_objects()
df.dtypes
# a int64
# b object # 因為b列加了引號,推斷成了字串
# dtype: object