pandas:様々な【データ変換】方法
目次
はじめに
ここに書いてあること
- データフレームに含まれるデータの変換方法
- インデックス番号リセット…df.reset_index
- データ型変更…df.vlaues
- データ一括変換…df.apply、lambda(lambdaはPython)
前提
- データ(データフレーム)の作成
サンプルコード
行のインデックス番号のリセット
データ作成
import pandas as pd
df = pd.DataFrame({'a':['01','02','03'],'b':['x','y','z'],'c':[10,20,30]})
df.loc[5]=['05','p',50]
print(df)
print(df.shape)
a b c 0 01 x 10 1 02 y 20 2 03 z 30 5 05 p 50 (4, 3)
- サイズ(4,3)のデータ(データフレーム)を作成
- インデックス番号0~2
- 最初のデータフレーム作成で3行作成
- インデックス番号5
- データフレームの更新で1行追加
- 連番だと次は3になるが5で追加した
インデックス番号をリセット
df.reset_index(drop=True,inplace=True)
print(df)
a b c 0 01 x 10 1 02 y 20 2 03 z 30 3 05 p 50
- df.reset_indexを使う
- インデックス番号が5から3になった(0~3の連番)
- drop=True
- 元のインデックス番号を保持するかどうか
- Trueは保持しない
- drop=Falseがデフォルト値
- inplace=True
- 元のデータフレームを更新するかどうか
- Trueは更新する
- inplace=Falseがデフォルト値
ndarray(NumPy配列)に変換
データ作成
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(12).reshape(3,4), columns=['a','b','c','d'])
print(df)
print(df.shape)
a b c d 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 (3, 4)
- サイズ(3,4)のデータ(データフレーム)を作成
一部取り出してndarrayに変換
p = df[0:2][['a','b','c']]
q = df[0:2][['a','b','c']].values
print(p)
print(type(p))
print(q)
print(type(q))
a b c 0 0 1 2 1 4 5 6 <class 'pandas.core.frame.DataFrame'> [[0 1 2] [4 5 6]] <class 'numpy.ndarray'>
- p
- データを絞り込み抽出
- 絞り込んだだけなのでDataFrameのまま
- q
- df.valuesを使う
- データ型をndarray(NumPy配列)に変換
一括データ変換
データ作成
import pandas as pd
df = pd.DataFrame({'id':['01','02','03','04','05'],'key':[1,3,2,3,1],'key_value':['','','','',''],'value':[3,4,7,6,5],'sq':['','','','','']})
key_list = {1:'first',2:'second',3:'third'}
print(df)
print(df.shape)
print(key_list)
id key key_value value sq
0 01 1 3
1 02 3 4
2 03 2 7
3 04 3 6
4 05 1 5
(5, 5)
{1: 'first', 2: 'second', 3: 'third'}
- df
- サイズ(5,5)のデータ(データフレーム)
- key_value列とsq列がブランクになっている
- この2列を次項で一括更新する
- key_list
- ディクショナリ型
- key値1,2,3に対してvalue値first,second,thirdを持っている
例1:べき乗を計算
df['sq']=df['value']**2
print(df)
id key key_value value sq 0 01 1 3 9 1 02 3 4 16 2 03 2 7 49 3 04 3 6 36 4 05 1 5 25
- value列のデータを元にべき乗(累乗)を計算
- sq列に結果を格納している
- 左辺をdf['value’](またはdf.valueでも可)にすると元のデータを直接更新
例2:関数で更新
df['key_value']=df['key'].apply(lambda x:key_list[x])
print(df)
id key key_value value sq 0 01 1 first 3 9 1 02 3 third 4 16 2 03 2 second 7 49 3 04 3 third 6 36 4 05 1 first 5 25
- lambda x:key_list[x]
- Pythonのlambdaを使って関数作成
- ディクショナリkey_listを使って値を取得
- df['key’].apply(…)
- 計算元データはkey列のデータ
- df.applyによって引数に指定した関数の処理が実行できる
- 結果をkey_value列に格納している
文字列をリストに変換する
はじめに
- pandasではデータをCSVデータから読み込むことがよくあります
- CSVデータに[1,2,3]のようなリストがあっても文字列として読み込まれます
- リスト型として処理したい場合、文字列→リストに変換する必要が出てきます
データ作成
import pandas as pd
import ast
df = pd.DataFrame({'id':['01','02','03'],'value':["[1,2,3]","[4,5,6]","[7,8,9]"]})
a = type(df['value'][0])
print(df)
print(df.shape)
print(a)
id value 0 01 [1,2,3] 1 02 [4,5,6] 2 03 [7,8,9] (3, 2) <class 'str'>
- サイズ(3,2)のデータ(データフレーム)を作成
- import ast
- 文字列をリストに変換するのにast.literal_evalを利用する
- a
- データフレームの表示では文字列かどうか判断できない
- df['value’][0]で1セルのデータ取り出し
- typeで型を確認するとstr(文字列型)となっていることが分かる
全文
df['value'] = [ast.literal_eval(x) for x in df['value']]
b = type(df['value'][0])
print(df)
print(b)
id value 0 01 [1, 2, 3] 1 02 [4, 5, 6] 2 03 [7, 8, 9] <class 'list'>
- 見た目は同じに見える
- b
- データタイプを確認するとlistになっている
- 変換の仕組みは以降で説明
部分実行(ast.literal_eval(…))
p = ast.literal_eval('1')
q = ast.literal_eval('1.')
r = ast.literal_eval('[1,2]')
print(p)
print(type(p))
print(q)
print(type(q))
print(r)
print(type(r))
1 <class 'int'> 1.0 <class 'float'> [1, 2] <class 'list'>
- ast.literal_eval(…)の動き
- 文字列を渡すと適切なデータ型に変換する
- '1’…int型に変換
- '1.’…float型に変換
- '[1,2]’…list型に変換
部分実行([x for x in …])
s = [x for x in pd.Series(['a','b'])]
print(s)
print(type(s))
['a', 'b'] <class 'list'>
- Pythonのリスト内包表記
- ループの元になる部分が全文ではpandasのDataFrameになっている
- 動きの解説
- 簡単に1列(Series)で考える
- 'a’と’b’の2つの文字列があるので、2回ループする
- 展開されて[]内に収まるため、['a’, 'b’]となる
- 全文では
- ast.literal_eval(x)変換され、適切なデータ型に変換される
- 作成されたリスト型が元のデータフレームのvalue列に代入される
- 結果、value列の全データが適切なデータ型に変換される
