カテゴリー

pandas

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

2021年9月14日

こんな人にオススメ

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

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

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

列0 列1 列2 列3
date 2021/9/14 1 1.5
time 13:50:12 2 2.7
tool A device 3 3.8
11 11.3
10 10.4
9 10
8 8.5
7 7
6 6.7
5 5.9
4 4.7

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

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

python環境は以下。

  • Python 3.9.6
  • pandas 1.3.1

運営者のメガネです。YouTubeTwitterInstagramも運営中。

自己紹介はこちらから、お問い合わせはこちらからお願いいたします。

運営者メガネ

作成したコード全文

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で行を表す& ...

続きを見る

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

こんな人にオススメ ネストされた ...

続きを見る

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

こんな人にオススメlistは+記号で配 ...

続きを見る

スマホ

2023/1/21

【Galaxy S22 Ultraレビュー】これが最高峰

こんな人におすすめ 2022年最強のスマホGalaxy S22 Ultraって実際使った感じどうなの ...

完全ワイヤレスイヤホン(TWS)

2023/1/15

【SENNHEISER MOMENTUM True Wireless 3レビュー】高レベルでバランス型の高音質イヤホン

こんな人におすすめ SENNHEISER MOMENTUM True Wireless 3って実際のところどうなの? 評判は良い ...

完全ワイヤレスイヤホン(TWS)

2023/1/14

【SONY WF-1000XM4 vs SENNHEISER MTW3】MTW3を選んだ決定的な3つの理由

こんな人におすすめ 執筆者は「SONY WF-1000XM4」「SENNHEISER MOMENTUM True Wireless 3」両方を持っている ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/1/5

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

マウス

2023/1/14

【Logicool MX ERGOカスタム】Logi Optionsのジェスチャーボタン設定内容

こんな人におすすめ Logicool MX ERGOをもっと上手に効率的に使いこなしたい。 ボ| ...

生活に役立つ

2023/1/8

【メガネ厳選】クソ便利に使っているサービスやアイテム達

このページでは執筆者「メガネ」が実際に使って便利だと感じているサ ...

完全ワイヤレスイヤホン(TWS)

2023/3/24

【SONY WF-1000XM4レビュー】神とゴミのハーフ&ハーフ

こんな人におすすめ SONYのフラグシップモデル「SONY WF-1000XM4」ってどれくらい性 ...

スイッチボット

2023/1/14

【SwitchBot Hub Mini】アプリにないエアコンなどの家電をその他で登録する方法

こんな人におすすめSwitchBot Hub Miniに我が家のエアコンを登録したいけど、SwitchBotア ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

ベンチャー企業のWebエンジニア駆け出し。独学のPythonで天文学系の大学院を修了→新卒を1.5年で辞める→転職→今に至る。
常時金欠のガジェット好きでM1 MacBook Pro x Galaxy S22 Ultraの狂人。

自己紹介と半生→変わって楽しいの繰り返し レビュー依頼などお問い合わせ Twitter@m_ten_pa

-pandas
-,