そもそもcastとは?
まず英語の意味で見てみましょう。
Cast = 「配役」や「割り当てる」などの意味があります。
よく「豪華キャストで送る〜」みたいな言い方がありますが「豪華配役/出演者」ということですね。
意味を見てわかる通りcastは何かに対して何かを割り当てるということです。
したがってプログラミングではcastはデータ型の変換を意味します。
普通、Pythonでは入力したデータに応じて、Pythonが自動的にデータ型を決めてくれます。(動的型付けと言います)
しかし、castをすることによりデータ型を手動で決定/変更することができます。
それではCastをしていきましょう!以下のCastをしていきます
- 組み込み型(e.x. 数値型、str型)
- データフレーム型内の要素
- Array型内の要素
標準関数のcast e.x. int, str, list
よく使われる組み込み型
- bool
- int
- float
- str
- list
- tuple
- dict
ここでは取り上げませんが、他にも組み込み型があります。
興味のある方は下記参照してみてください。
組み込み型
まず、変数の定義をしていきます。(変数名を格データ方の頭文字にしています。)
b = True # bool
i = 5 # int
f = 10.5 # float
s = '55' # str
l = [10, 45, 'Tako'] # list
t = (6, 8.5, 'cat') # tuple
d = {'Mike': 'America', 'Aya': 'Japan', 'sung': 'Korea'} # dict
意図通りのデータが入っているかデータ型をみていきます。
type(変数)で見ることができます。
print(type(b))
print(type(i))
print(type(f))
print(type(s))
print(type(l))
print(type(t))
print(type(d))
<class 'bool'>
<class 'int'>
<class 'float'>
<class 'str'>
<class 'list'>
<class 'tuple'>
<class 'dict'>
意図通りの値が入っています。
次にcastをしていきます。まず、bool, int, float, strを変更してみます。
例) strをintに変換 ⇨ int(strの変数) と書く
b_to_i = int(b) # bool -> int
i_to_s = str(i) # int -> bool
f_to_i = int(f) # float -> int
s_to_f = float(s) # str -> float
変換完了しました。
実際に変換できているかtype()で見ていきましょう。
print(type(b_to_i))
print(type(i_to_s))
print(type(f_to_i))
print(type(s_to_f))
<class 'int'>
<class 'str'>
<class 'int'>
<class 'float'>
castができていますね。
同様の方法でlistやdict内の要素も変換できます。
ちなみに、bool -> int/floatでもcast可能です。
Trueだと1/1.0でFalseだと0/0.0で表示されます。
またfloat -> intは小数点以下が切り捨てられています。
見てみましょう。
print(b_to_i) # Trueなので1が入っている
print(f_to_i) # 小数点以下切り捨て
1
10
Castができない場合
# NG例
s = 'Hello'
not_s_to_i = int(s) # 文字列はcastできない
ValueError Traceback (most recent call last)
<ipython-input-21-1313b5f470bf> in <module>
1 # NG例
2 s = 'Hello'
----> 3 not_s_to_i = int(s)
ValueError: invalid literal for int() with base 10: 'Hello'
数字ではない文字列はint関数ではcastすることができません。
次に他のデータ型からlist、tuple、dictへの変換をしてみましょう。まずは変換される変数の定義とデータ型の確認。
s = 'Hello' # str
l = [10, 45, 'Tako'] # lsit
l2 = [['Mike', 'America'], ['Aya', 'Japan'], ['sung', 'Korea']] # list of list
t = (6, 8.5, 'cat')
print(type(s))
print(type(l))
print(type(l2))
print(type(t))
<class 'str'>
<class 'list'>
<class 'list'>
<class 'tuple'>
それではcastをしていきます。
cast後の型とデータもみましょう。
s_to_l = list(s) # str -> list
t_to_l = list(t) # tuple -> list
s_to_t = tuple(s) # str -> tuple
l_to_t = tuple(l) # list -> tuple
l2_to_d = dict(l2) # list of list -> dict
print(type(s_to_l))
print(s_to_l)
print(type(t_to_l))
print(t_to_l)
print(type(s_to_t))
print(s_to_t)
print(type(l_to_t))
print(l_to_t)
print(type(l2_to_d))
print(l2_to_d)
<class 'list'>
['H', 'e', 'l', 'l', 'o']
<class 'list'>
[6, 8.5, 'cat']
<class 'tuple'>
('H', 'e', 'l', 'l', 'o')
<class 'tuple'>
(10, 45, 'Tako')
<class 'dict'>
{'Mike': 'America', 'Aya': 'Japan', 'sung': 'Korea'}
str型をlist/tupleに変換する場合、1文字ずつ分解され保存されます。
リストのリストの場合、リストの中の各リストが2つのデータを保有する場合、dict型に変換可能です。
1つ目がKeyになり、2つ目がValueになります。
また、通常のlist/tupleであっても各データが2文字であれば変換可能です。(使用の機会があまりなさそうなので割愛します。)
PnadasやNumpy
他にもPandasのDataFrameオブジェクトとSeriesオブジェクトの要素をメソッドを使うことで変換できたり、Numpyでもarrayの要素をメソッドを使うことで変換できます。
import pandas as pd
import numpy as np
# pandas例
df = pd.read_csv('./data/cls_train.csv') # Titanic - https://www.kaggle.com/c/titanic/data?select=train.csv
print('変更前: ', df['Age'].dtypes)
df['Age'] = df['Age'].astype(str) # Age列の要素の変換
print('変更後 ', df['Age'].dtypes)
# numpyの例
lst = [52.5, 2, 5, 10.999]
n_array = np.array(lst, dtype=np.float64) # float64型
print('変更前: ', n_array.dtype)
int_arr = n_array.astype('int') # float -> int
print('変更前: ', int_arr.dtype)
変更前: int64
変更後: object
変更前: float64
変更前: int64
このように簡単に変更できます。
ちなみにデータフレームはstr型にするとobjectという名前に変わります。
もっと詳しく見たい人は公式ドキュメントを見てください
Pandas
Numpy
まとめ
さまざまなCast方法がありました。
標準関数を使ってのcastは標準関数(変えたい値)で簡単に変えれれ、pandasとnumpyはastypeメソッドを簡単につかって変換できます。
ここでは触れませんが、int64、int32、int16などビット指定ができてメモリ消費を抑えたり、パソコンの環境に合わせることができます。
個人的な考えですが、castが1番活躍するのは、計算などで数字を扱う時ではないでしょうか?
例えばユーザーからのインプット(input())はstr型になってしまうので、数字のインプットでも計算などで使うことができません。
そのような時にcastを使うことで解決できます。意外と使える技術だと思います。
指摘などありましたら、コメントお願いします。