カテゴリー

pandas

【pandas&NaN】データフレームdfのNaN部分を空にする

2021年9月14日

こんな人にオススメ

行の数が異なる、複数列を持ったcsvファイルをpandasで読み込んだんだけど、データフレームに勝手にNaNが入ってる。

特に支障はないけど、いつもNaNがあるからなんか気持ち悪い。どうにかして表示だけでも消せない?

ということで、今回は形の歪なcsvファイルを読み込んだときに発生するNaNを削除する方法について解説する。今回は以下のような歪なデータを使用する。

列0列1列2列3
date2021/9/1411.5
time13:50:1222.7
toolA device33.8
1111.3
1010.4
910
88.5
77
66.7
55.9
44.7

初めの0, 1列分は取得データが存在、日付と取得データ名が書かれているが、その下は空白となっている。2, 3列目でようやくデータがある。

このデータをシンプルにpandasで読み込むとNaNが発生してしまって見た目が悪い。もちろんあってもなくてもそれは個人・したいことの勝手。

python環境は以下。

  • Python 3.9.6
  • pandas 1.3.1
スポンサーリンク
スポンサーリンク

運営者のメガネです。TwitterInstagramも運営してます。

自己紹介はこちらから、お問い合わせはこちら。

運営者メガネ

作成したコード全文

csvを読み込んでデータフレームを作成

import pandas as pd

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# データの読み込み

file = 'data_file.csv'
names = ['items', 'values', 'x', 'y']  # ヘッダ名
df = pd.read_csv(file, names=names)
print(df)
#    items     values   x     y
# 0   date  2021/9/14   1   1.5
# 1   time   13:50:12   2   2.7
# 2   tool   A device   3   3.8
# 3    NaN        NaN   4   4.7
# 4    NaN        NaN   5   5.9
# 5    NaN        NaN   6   6.7
# 6    NaN        NaN   7   7.0
# 7    NaN        NaN   8   8.5
# 8    NaN        NaN   9  10.0
# 9    NaN        NaN  10  10.4
# 10   NaN        NaN  11  11.3

まずはcsvファイルを読み込む。今回のデータではヘッダ名が設定されていないので、こっちで勝手にヘッダ名を決めた。ヘッダ名は引数namesで行える。

read_csvで無事にデータを読み込むことができたが、ここで本記事の問題に直面する。それは、items, values列の3行目以降がNaNであるということ。

今回はこれを解決する。

データフレームをcsvへ書き込み

x, y = df['x'], df['y']
df['y2'] = y * 2

print(df)
#    items     values   x     y    y2
# 0   date  2021/9/14   1   1.5   3.0
# 1   time   13:50:12   2   2.7   5.4
# 2   tool   A device   3   3.8   7.6
# 3    NaN        NaN   4   4.7   9.4
# 4    NaN        NaN   5   5.9  11.8
# 5    NaN        NaN   6   6.7  13.4
# 6    NaN        NaN   7   7.0  14.0
# 7    NaN        NaN   8   8.5  17.0
# 8    NaN        NaN   9  10.0  20.0
# 9    NaN        NaN  10  10.4  20.8
# 10   NaN        NaN  11  11.3  22.6

とその前に、そもそも再度csvへと書き込んだ時にはどうなるのかを見ておく。別データということを確認しやすいように、データを追加しておく。

csv上ではNaNはないように見える

new_file = file.replace('.', '_new.')  # ファイル名を変更
# df.to_csv(new_file, index=False)

データフレームを新しいcsvファイルへと書き込んで、実際にその出力を見てみると、NaNの文字はなく何も入っていないということが確認できる。

ジャンプで空に行ってもない

なお、ちゃんと空になっているのかを確認するために楽な方法にはジャンプ機能という機能を使用する。これはmacの場合だと「ctrl g」で可能。多分Windousもこれ。

ジャンプで「セル選択」に進み「空白」の欄を選択して確定すると、囲った範囲で空白になっているセルのみを選択することができる。

実際に選択した時の状態が上の画像で、ちゃんと空になっていることがわかる。なお、スペースが入っている場合は空白としてみなされないので注意。

dfからNaNを消すにはfillna

df_nonan = df.fillna('')  # NaNを空と比較
print(df_nonan)
#    items     values   x     y    y2
# 0   date  2021/9/14   1   1.5   3.0
# 1   time   13:50:12   2   2.7   5.4
# 2   tool   A device   3   3.8   7.6
# 3                     4   4.7   9.4
# 4                     5   5.9  11.8
# 5                     6   6.7  13.4
# 6                     7   7.0  14.0
# 7                     8   8.5  17.0
# 8                     9  10.0  20.0
# 9                    10  10.4  20.8
# 10                   11  11.3  22.6

csvファイル上ではNaNは出てこないということはわかった。でも肝心のpythonの出力上でのNaNは解決していない。

どうやれば表示から消せるかというと、一番簡単な方法は上のようにfillnaを使用するという方法。今回で言えば空にしたいから''を選択すればいい。

これでデータのない部分がNaNから空に変換される。イメージは置き換わる。

空白ではなく空(から)

# 削除した部分は空白ではなく空っぽ
for i in df_nonan['items']:
    val = f"{i:4s}"  # 中身を取り出し
    tf1 = f"{i == ''}"  # 空と比較
    tf2 = f"{i == ' '}"  # 空白と比較
    print(val, tf1, tf2)
# date False False
# time False False
# tool False False
#      True False
#      True False
#      True False
#      True False
#      True False
#      True False
#      True False
#      True False

filllna('')で空に置き換えたが、実際に空かどうかを確かめたい。確かめ方として今回は1要素ずつ比較してみた。結果は''と等しいにTrueなのでから出ることが確認できる。

csvで確認してもやっぱり空

new_file = file.replace('.', '_new2.')
df_nonan.to_csv(new_file, index=False)

csvファイルとして出力して中身をExcelのジャンプで空白セルチェックをすると、ちゃんと空白=pythonでいう空になっていることが確認できる。

空白にするともちろん空白に

# 空白にするともちろん空白が入る
df_space = df.fillna(' ')  # NaNを空と比較

# 削除した部分は空白ではなく空っぽ
for i in df_space['items']:
    val = f"{i:4s}"  # 中身を取り出し
    tf1 = f"{i == ''}"  # 空と比較
    tf2 = f"{i == ' '}"  # 空白と比較
    print(val, tf1, tf2)
# date False False
# time False False
# tool False False
#      False True
#      False True
#      False True
#      False True
#      False True
#      False True
#      False True
#      False True

当たり前だが、fillnaに空白(スペース)を指定すると、NaNの代わりに入るのが空から半角スペースになる。

したがって、forで中身を書くにする際には空ではなく空白と等しいかの判定時にTrueで返される。

csvで確認しても空白

new_file = file.replace('.', '_new3.')
df_space.to_csv(new_file, index=False)

今回は半角スペースを入れたのでジャンプでの空白せるには引っかからない。ということで、ここでは条件付き書式で半角スペースと等しいセルに赤色を付加した。

結果は半角スペースを入れたセルは赤くなった。予想通り。

そもそも読み込むときにNaNを使用しない

file = 'data_file.csv'
names = ['items', 'values', 'x', 'y']  # ヘッダ名
df_ini = pd.read_csv(file, names=names, na_filter=False)
print(df_ini)
#    items     values   x     y
# 0   date  2021/9/14   1   1.5
# 1   time   13:50:12   2   2.7
# 2   tool   A device   3   3.8
# 3                     4   4.7
# 4                     5   5.9
# 5                     6   6.7
# 6                     7   7.0
# 7                     8   8.5
# 8                     9  10.0
# 9                    10  10.4
# 10                   11  11.3

最後に大どんでん返し。これまではNaNになってしまった→NaNを空に置き換えようという流れだったが、そもそもデータを読み込む際にNaNを表示しなければいい。

初めから表示しない方法にはread_csvの引数na_filterFalseにしてあげればいい。Falseにすることで、データがない部分はそのまま出力される。

要するにデフォルトではデータがない部分はNaNにするという処理をスキップということ。これば一番楽。

ちょっとしたことだけど疑問に持てる

ということで、今回はpandasのデータフレームで表示されるNaNを如何にして表示しなくするかについて解説した。

正直、表示使用がしまいが割とどうでもいいことだが、こんな小さなことでも気にしてしまうのが初心者たること。慣れるとどうでもよくなる。

初心を忘れずにという言葉にはこのような、慣れると気にしなかったことも気にすると言う意味も含まれているのかもしれない。

関連記事

【pd&MultiIndex】pandasで複数インデックスの設定と書き読み

続きを見る

多項式関数のグラフ
【辞書&pandas】dict{name: , val: {a: [~], b:[~]}}のpandas化

続きを見る

【辞書の結合】dictのマージ

続きを見る

関連コンテンツ

スポンサーリンク

Amazonのお買い物で損したない人へ

1回のチャージ金額通常会員プライム会員
¥90,000〜2.0%2.5%
¥40,000〜1.5%2.0%
¥20,000〜1.0%1.5%
¥5,000〜0.5%1.0%

Amazonギフト券にチャージすることでお得にお買い物できる。通常のAmazon会員なら最大2.0%、プライム会員なら2.5%還元なのでバカにならない。

ゲットしたポイントは通常のAmazonでのお買い物に使えるからお得だ。一度チャージしてしまえば、好きなタイミングでお買いものできる。

なお、有効期限は10年だから安心だ。いつでも気軽にAmazonでお買い物できる。

Amazonチャージはここから出来るで

もっとお得なAmazon Prime会員はこちらから

30日間無料登録

執筆者も便利に使わせてもらってる

スポンサーリンク

  • この記事を書いた人

メガネ

独学でpythonを学び天文学系の大学院を修了。 ガジェット好きでMac×Android使い。色んなスマホやイヤホンを購入したいけどお金がなさすぎて困窮中。 元々、人見知りで根暗だったけど、人生楽しもうと思って良い方向に狂ったために今も人生めちゃくちゃ楽しい。 pythonとガジェットをメインにブログを書いていますので、興味を持たれましたらちょこちょこ訪問してくだされば幸いです🥰。 自己紹介→変わって楽しいの繰り返し

-pandas
-,