pandasを使ったデータ変換をしていてfloat型の列を整数部のみにしたい場合、「astype」などを使用してint型に変換すれば簡単に実現できるかと思いますが、そこに欠損値が含まれている場合うまく変換できなかったので、変換する方法を試してみました。
尚、タイトルで"int型"に変換する方法と書いてないのは理由があります。
目次
準備
テストデータは以下を使用します。
$ cat test.csv "age","point" "12","null" "13","null" "14","1.0" "15","null" "16","2.0" "17","null"
CSVファイルをpandasで読み込んでおきます。
>>> import pandas as pd >>> import np >>> df = pd.read_csv('test.csv') >>> df age point 0 12 NaN 1 13 NaN 2 14 1.0 3 15 NaN 4 16 2.0 5 17 NaN
できなかったパターン
最初に実現しようとしてできなかったint型に変換するパターンです。
やりたいこととしてはシンプルで、欠損値を一旦別の値に変換してfloat→int変換した後に、欠損値に戻す方法を試しました。
float→int変換については想定通り変換できました。
>>> df['point_int']=df['point'].fillna(99).round().astype('int64') >>> df age point point_int 0 12 NaN 99 1 13 NaN 99 2 14 1.0 1 3 15 NaN 99 4 16 2.0 2 5 17 NaN 99
ただ、そのあと欠損値にreplaceで戻そうとした際にデータ型がfloat型に戻ってしまい、本来整数部のみ表示したい1や2が1.0と2.0になってしまいました。
この方法では自分のやりたいことはできませんでした。
>>> df['point_int'].replace(99, np.nan) 0 NaN 1 NaN 2 1.0 3 NaN 4 2.0 5 NaN Name: point_int, dtype: float64
できたパターン
かなり力技にはなってしまうのですが、自分のやりたいことができたパターンです。
一度文字列型に変換した後、文字列として小数部で除去し欠損値だけ文字列の"nan"から"NaN"に戻すようにしました。
int型にはできませんでしたが、私が今回やりたかったのは整数部のみに変換して文字列としてCSV出力することでしたので、これで特に問題はなかったです。
>>> df['point_str']=df['point'].astype('str').str.replace('\.0','').replace('nan', np.nan) >>> df age point point_int point_str 0 12 NaN 99 NaN 1 13 NaN 99 NaN 2 14 1.0 1 1 3 15 NaN 99 NaN 4 16 2.0 2 2 5 17 NaN 99 NaN
感想及び所感
調べてみてもやりたかったことを実現する方法が見つからなかったので、備忘として書きました。
pandasを使う例だと良くデータ分析時の変換方法が出てきて、欠損値を全体の平均値にするなどが散見されたのですが、今回はデータ分析ではなく単純にデータクレンジングの用途で使いたかったので、その方法は取れませんでした。
スマートではない解決方法でしたので、もし他に良いやり方をご存じの方がいれば、ぜひコメントいただけると嬉しいです。