Help us understand the problem. What is going on with this article?

pandasで外部ファイルを読み込むときのdtype=strに気を付けろ

More than 1 year has passed since last update.

2019/04/05更新
現在のバージョン(0.24.1)ではxlsxの挙動がcsvと同じになっていました。
JSONは相変わらずです。
また気づき次第更新します。

to 昨日の私

何かしらのデータをDataFrameに変換する際、"001"の頭の00が取れるなど意図しない挙動を避けるためにいったん全部文字列型で受け取ろうという設定がdtype=strです。
これに於けるnullの扱いがcsv、xlsx、jsonでそれぞれ違ったのでメモ。

用意したデータ

test.csv
name,code
すし,001
ピザ,002
カレー,
test.json
[
    {"name":"すし", "code":"001"},
    {"name":"ピザ", "code":"002"},
    {"name":"カレー", "code":null}
]

xlsxはcsvと同じなので省略

読み込み

import pandas
import pathlib
import IPython.display

csv_path = pathlib.Path('./test.csv')
csv = pandas.read_csv(csv_path, dtype=str, encoding='utf8')
display(csv)
name code
0 すし 001
1 ピザ 002
2 カレー NaN
xlsx_path = pathlib.Path('./test.xlsx')
xlsx = pandas.read_excel(xlsx_path, dtype=str, encoding='utf8')
display(xlsx)
name code
0 すし 001
1 ピザ 002
2 カレー nan
json_path = pathlib.Path('./test.json')
json = pandas.read_json(json_path, dtype=str, encoding='utf8')
display(json)
code name
0 001 すし
1 002 ピザ
2 None カレー

見事にバラけました。

fillna()

それぞれのDataFrameにnullを一括置換するfillna()をあててみます。

csv.fillna("000", inplace=True)
display(csv)
name code
0 すし 001
1 ピザ 002
2 カレー 000

csvはうまくいきましたが…

xlsx.fillna("000", inplace=True)
display(xlsx)
name code
0 すし 001
1 ピザ 002
2 カレー nan
json.fillna("000", inplace=True)
display(json)
code name
0 001 すし
1 002 ピザ
2 None カレー

xlsxとjsonでは失敗します。

原因

"nan"、"None"という文字列に変換されるためです。
replace()しましょう。

nicco_mirai
経理マンとソフトウェア開発業務のハイブリッドでしたがいつの間にか開発専業になりました。業務はPythonがメイン、他Go/VB.NET/C#/JSなど。時々VBAやGASもやります。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away