[go: up one dir, main page]

🏄‍♂️

Pandasで「野根(None)」という地名が欠損値(NaN)になってしまった話

に公開

Pandasの read_csv における欠損値文字列の扱い

Pythonのデータ解析ライブラリPandasでは、CSVファイルを読み込む際(pd.read_csv())、特定の文字列が自動的に NaN (欠損値)として扱われるという仕様があります。

ドキュメントによると、デフォルトで以下の値がNaNと解釈されます。

By default the following values are interpreted as NaN: “ “, “#N/A”, “#N/A N/A”, “#NA”, “-1.#IND”, “-1.#QNAN”, “-NaN”, “-nan”, “1.#IND”, “1.#QNAN”, “<NA>”, “N/A”, “NA”, “NULL”, “NaN”, “None”, “n/a”, “nan”, “null “.

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

実際に起きた問題: 野根(None) という地名

この仕様の影響で、私たちの開発している歴史地図ウェブサービス「れきちず」のデータ処理中に思わぬ問題が発生しました。

https://rekichizu.jp/

データセットの中に「野根(のね)」という地名があり、その英語表記として "None" を付与しました。

https://ja.wikipedia.org/wiki/野根町

ところが、この「None」は、Pandasで読み込むと自動的にNaNとして扱われてしまいました。

その結果、作成したGeoJSONの内容が name_en: NaN となってしまいました。この状態でtippecanoeによるベクトルタイル生成を行うと、 JSON does not allow NaN というエラーが発生しました。もし事前に欠損値を全てnullや空文字に変換していたら、エラーは出ないため、この事象は発覚しなかったでしょう...

解決策: keep_default_na=False を設定

この問題は read_csv() のオプションを調整することで解決できます。

デフォルトでは keep_default_na=True になっているため、これを False に設定します。

これにより、デフォルトのNaN解釈リストが無効化され、「None」などの文字列がそのまま文字列として扱われます。

さらに、独自に欠損値とみなしたい文字列を指定したい場合は na_values オプションを併用できます。

pd.read_csv("input.tsv", keep_default_na=False, na_values=["NaNにしたい文字列"])

また、na_filter という、「欠損値の検出」を制御するオプションも用意されています。空文字や na_values に該当する値を検出しない場合(データに NA の値が全くない場合)、 na_filter=False とすることで、大規模データの読み込みでパフォーマンスを改善できる可能性があるそうです。

余談: 「野根」は四国の高知にあります

「野根」は、現在の高知県にあります。

「れきちず」での該当箇所

図: 「れきちず」での該当箇所

1959年に「野根町」と「甲浦(かんのうら)町」が合併し、「東洋町」が発足しました。東洋町は高知県の最東端に位置し、徳島県と接する自治体です。

私は徳島に住んでいたころ、何度か東洋町を訪れて、宿泊したこともあります。その名の通り東に太平洋を望み、ビーチではサーフィンを楽しむ人の姿も見られる、静かで素敵なところでした。

東洋町の海岸

東洋町でのキャンプ

室戸岬をぐるっと一周139km走る自転車イベント「安芸・室戸パシフィックライド」では、野根中学校がエイドステーションになっていました。

安芸・室戸パシフィックライドでの野根中学校エイドステーション

このようなかたちで再会するとは思いませんでした 🤭

MIERUNEのZennブログ

Discussion