2015年12月05日

pandasで例外を無視しつつObject(文字列)を数値に変換する

何行かエラーレコードが混じってる場合、astypeで型を変えようとしても落ちる。

例えば下記は1つ目のカラムが数値、2つ目のカラムが文字列を想定していたけど、途中、数値が入るべきところに文字が入ってしまっている。

df = pd.DataFrame( [['0', 'zero'], ['1', 'one'], ['B', 'two'], ['3.0', 'three']], columns=['num', 'word'] )

  #=>    num   word
  #=> 0    0   zero
  #=> 1    1    one
  #=> 2    B    two
  #=> 3  3.0  three

これをastype(np.float)するとエラーになる。

df.num.astype(np.float)
  #=> ValueError: could not convert string to float: 'B'

applyの中でtry catchしてfloatに変換するのもイケてない。

def float_value(x):
    try:
        return float(x)
    except ValueError:
        return np.nan

df.num.apply(float_value)
  #=> 0     0
  #=> 1     1
  #=> 2   NaN
  #=> 3     3

何かないかと思って調べてみたら、convert_objectsというものが用意されていた。

df.num.convert_objects(convert_numeric=True)

  #=> 0     0
  #=> 1     1
  #=> 2   NaN
  #=> 3     3

エラーレコードについては-1とし、np.floatではなくnp.intとして保持したい場合は、下記のように書くのが良いだろうか。

df.num.convert_objects(convert_numeric=True).fillna(-1).astype(np.int)

  #=> 0    0
  #=> 1    1
  #=> 2   -1
  #=> 3    3