らふのプログラミングメモ

プログラミングメモです。

Pandasの欠損値についての取り扱い方法 その1 とりあえず消してみよう

分析したいデータには大体が欠損値がつきものだと思います。

というわけで、まずは欠損値についての取り扱いは以下の2種類かと思います。

  • 削除
  • 穴埋め(置き換えですね)

今回は削除についてまとめていきたいと思います。

消してしまおう!(削除)

データによっては消してしまったほうがいいものもある(かもしれません)
というこで、まずは消してしまう方法から考えていきましょう。

削除方法として
- 該当するデータを1つずつ確認して削除する方法
- 一括で変換(dropna)をする方法
の2種類があります。

テストデータを作ってみます。

name age add English math
0 aaa Nan Tokyo 80 90
1 bbb 20 Osaka 85 80
2 ccc 22 Nagoya 90 85

aaaさんの年齢を欠損させておきます。

import pandas as pd
import numpy as np

data = {"name":["aaa","bbb","ccc"],"age":[np.nan,20,22],"add":["Tokyo","Osaka","Nagoya"],"English":[80,85,90],"math":[90,80,85]}

df = pd.DataFrame(data)
  • dropna()を使ってデータを一括で消去してしまおう。
df_after = df.dropna()
print(df_after)

df_afterの結果:

name age add English math
1 bbb 20 Osaka 85 80
2 ccc 22 Nagoya 90 85

aaaさんのデータが全消去されました。

今回は1つのデータのみ欠損値があっただけなので、次は複数あった場合を確認してみましょう。

data2 = {"name":["aaa","bbb","ccc",np.nan,"EEE"],"age":[np.nan,20,22,20,18],"add":["Tokyo","Osaka","Nagoya",np.nan,np.nan],"English":[80,85,90,100,90],"math":[90,80,85,80,90]}

df2 = pd.DataFrame(data2)

df2の結果:

name age add English math
0 aaa Nan Tokyo 80 90
1 bbb 20 Osaka 85 80
2 ccc 22 Nagoya 90 85
3 NaN 20.0 NaN 100 80
4 EEE 18.0 NaN 90 90

これをdropna()を使って削除してみましょう。

df2_after = df2.dropna()

df2_afterの結果:

name age add English math
1 bbb 20 Osaka 85 80
2 ccc 22 Nagoya 90 85

この結果からわかるように、1つでもNanデータがあるとデータは削除されることがわかります。

<最終更新日:2021/09/21>
2021/09/21 投稿

NumPyのndarray その9 色々な型のデータが混在しているCSVファイルでもndarrayに読み込む方法

昨日はndarrayに色々な型のデータが混在したCSVファイルを読みこめなかった!というのをまとめました。

rafu.hatenablog.jp

なんとかして読み込めないの!?

無理だったと言われても。
なんとかならないもの?ということで調べてみました。

  • loadtxt()の引数で文字列として無理矢理読み込む方法。
  • genfromtxt()を使って、CSVファイルのデータのままの型で読み込む。

この2種類があるみたいです。

というわけで、前回と同じテストデータを使ってやってみましょう。

test.csv(文字コード:Shift-JIS)の中身 (1行目にはインデックスを入れてあります。)


名前,日付,テスト
Ito,2021/08/10,85
Suzuki,2021/08/10,80
Tanaka,2021/08/10,75


loadtxt()で文字列として強制的に読み込む。

まずはloadtxt()を使ってやってみましょう。
文字列として読み込みたいのでunicode_を指定してみました。
(ちなみに全て数値に指定してみたところ、文字列のところで昨日と全く同じエラーが出ました。)

import numpy as np

n_a = np.loadtxt("test.csv",delimiter = ",",encoding = "shift-JIS",dtype = "unicode_",skiprows = 1)

print(n_a)

print(n_a.dtype)

n_aの結果:
[ ["Ito" "2021/08/10" "85"]
["Suzuki" "2021/08/10" "80"]
["tanaka" "2021/08/10" "75"] ]

n_a.dtypeの結果:<U10

このようにdtypeにunicode_を設定することで、
数値も文字列(unicode文字列)としてndarrayに入れることができました。

genfromtxt()を使って、CSVファイルのデータのままの型で読み込む。

今度はgetfromtxt()を使ってみましょう。

import numpy as py

n_b = np.genfromtxt("test.csv",delimiter = ",", dtype = None, encoding = "shift-JIS",names = True)

print(n_b)

print(n_b.dtype)

n_bの結果:
[("Ito","2021/08/10",85) ("suzuki","2021/08/10",80) ("tanaka","2021/08/10",75)]
n_b.dtypeの結果:
[("名前”,"<U6"),("日付","<U10"),("テスト","<i4")]

これより、名前と日付は文字列(unicode文字列)で、
テストの値にはuint32の符号なし32ビット整数で入力をすることができました。

~ 注意点 ~
今回のように型が違ったものを読み込みたい場合、
genfromtxt()の引数で必ず以下のところは指定してください。

  • dtype = None
    Noneにすることでファイルの型をそのまま自動で割り振ってくれる。

  • names = True
    Trueで最初の1行目がフィールドの名前ということで除外して読み込む。

  • encoding = "shift-JIS"
    これは読み込みたいファイルのエンコードを設定してください。

<最終更新日:2021/09/16>
2021/09/16 投稿

NumPyのndarray その8 型がいろいろ混ざっているCSVファイルをndarrayに読み込んでみよう

昨日はndarrayに整数のみのCSVファイルを読みこむというのをまとめました。

rafu.hatenablog.jp

ここで1つ疑問が。 型を混ぜてndarrayに入力しようとした場合、どうなるんだろう?

なんでこのような疑問が出たの?

rafu.hatenablog.jp

上の記事でやってみましたが、
型を混ぜてndarrayに入力しようとした場合、
自動で型変換されていました。

ということは、今回も型変換されてしまうのか? 試してみたいと思います。

まずは以前と同じテストファイルを使ってみよう

前回と同じファイル(test.csv)を使ってみたら
どのように読み込まれるかをやってみたいと思います。
このファイルは文字列・日付・数値(int)が入ったものです。

例:
今回もtest.csvというCSVファイルを読み込んでみます。
CSVファイルの配置場所は、Pythonの実行環境と同じ場所においてみます。

python/
 ├ NNN.py(今回実行するファイル)
 ├ test.csv(読み込みたいCSVファイル)

test.csv(文字コード:Shift-JIS)の中身 (1行目にはインデックスを入れてあります。)


名前,日付,テスト
Ito,2021/08/10,85
Suzuki,2021/08/10,80
Tanaka,2021/08/10,75


実際にデータを取り込んでみよう!

NNN.py

import numpy as np

# loadtxtを使って区切り文字を使ったファイルの読み込みを行う。
# encoding:shift_JISのファイルなので指定します。
# delimiter:デフォルトは空白なので、カンマの指定をします。
# skiprows:1行目にインデックスがあるので、これを除外します。
n_array = np.loadtxt("test.csv", encoding = "shift_JIS" ,delimiter = "," , skiprows = 1 )
print(n_array)

結果:エラーが出ました。
内容:could not convert string to float: "Ito"

どうやら文字列が入っているものはダメなようです。

次に、名前を除外したCSVファイル(test3.csv)を作ってみます。

test3.csv


日付,テスト
2021/08/10,85
2021/08/10,80
2021/08/10,75


このtest3.csvを読み込むように変更して実行してみます。

n_array = np.loadtxt("test3.csv", encoding = "shift_JIS" ,delimiter = "," , skiprows = 1 )

すると、先ほどと同じようなエラーが出ました。
エラー内容:could not convert string to float: "2021/08/10"

これより、文字列はloadtxt()では読み込めないことがわかりました。


<最終更新日:2021/09/15>
2021/09/15 投稿

NumPyのndarray その7 ndarrayにCSVファイルを読み込んでみよう

PandasのDataFrameにCSVファイルを読み込むというのを以前まとめました。

rafu.hatenablog.jp

今回はndarrayにCSVファイルを読み込んでみたいと思います。

まずはテストデータを作ってみよう

NumPyの特徴が計算に特化しているということなので、
今回は数値のみ(int)のファイルを作成してみました。

例:
今回はtest2.csvというCSVファイルを読み込んでみよう
CSVファイルの配置場所は、Pythonの実行環境と同じ場所においてみる。

python/
 ├ MMM.py(今回実行するファイル)
 ├ test2.csv(読み込みたいCSVファイル)

test2.csv(文字コード:Shift-JIS)の中身


1,2,3
2,3,4
3,4,5


実際にデータを取り込んでみよう!

MMM.py

import numpy as np

# loadtxtを使って区切り文字を使ったファイルの読み込みを行う。
# encoding:shift_JISのファイルなので指定します。
# delimiter:デフォルトは空白なので、カンマの指定をします。
n_array = np.loadtxt("test.csv", encoding = "shift_JIS" ,delimiter = ",")
print(n_array)

n_arrayの結果:
[ [1. 2. 3.]
[2. 3. 4.]
[3. 4. 5.]]

n_arrayの結果に全て小数点がつきました。
ということで、型の確認をしてみたいと思います。

print(n_array.dtype)

n_array.dtypeの結果:float64

これより、CSVファイルには整数で入っていた数値が
ndarrayに取り込む際にfloat64型に変換されたことがわかります。



<最終更新日:2021/09/14>
2021/09/14 投稿

NumPyのndarray その6 ndarrayとSeriesを相互変換してみよう

先日はndarray⇄DataFrameの相互変換をまとめてみました。

rafu.hatenablog.jp

次は?ということで、ndarray⇄Seriesの相互変換をやってみたいと思います。

今回のテストデータとして、ndarrayに以下のデータを使用します。

10 20 30 40 50

まずはndarray→Seriesへの変換

ndarrayにインデックスをつけて変換することが可能です。
(何もつけないでいると自動で0から割り振られます。)

  • 実際にやってみよう
import numpy as np
import pandas as pd
# テストデータ作成
data = [10,20,30,40,50]
# テストデータをndarrayに入れる
a = np.array(data)
# ndarray→Seriesに変換。
s = pd.Series(a)
print(s)

sの結果:
今回はインデックスに何も指定をしていないので、
自動で0から割り振られました。

010
120
230
340
450

続いて、Series→ndarrayに変換してみよう。

DataFrame→ndarrayの時と同じように、Seriesのラベル情報は
ndarrayに変換される際に失われてしまいます。

  • 実際やってみよう
# print(s)の続き
n = np.array(s)
print(n)

nの結果: [10 20 30 40 50]

一番初めに作ったテストデータと同じものができあがりました。


<最終更新日:2021/09/13>
2021/09/13 投稿

NumPyのndarray その5 ndarrayとDataFrameを相互変換してみよう

今日は2次元配列のndarrayとPandasのDataFrameの相互変換してみたいと思います。

今回のテストデータとして、ndarrayに以下のデータを使用します。

90 80
80 85

 まずはndarray → PandasのDataFrameへの変換

  • 変換方法
    pandasのDataFrame関数を使えば、そのまま変換が可能です。

  • 実際にやってみよう

import pandas as pd
import numpy as np
#下準備用のデータ
data = [[90,80],[80,85]]
#ndarrayに入れました。
test = np.array(data)
#DataFrameに変換します
df = pd.DataFrame(test,columns = ["English","Math"])

#確認用:ndarray
print(test)
#確認用:DataFrame
print(df)
  • 結果

test:
[ [90 80]
[80 85] ]

df:

English Math
0 90 80
1 80 85

次にPandasのDataFrame → ndarrayへの変換

  • 変換方法 pandasのDataFrameは、numpy.array関数を使うことにより、
    ndarrayに変換することが可能です。

  • 注意点 DataFrameにはcolumnの名前がありますが、
    こちらの情報はndarrayに変換する際に失われてしまいます。

  • 実際にやって確認してみよう
    先ほどのdfの値を使用してみます。

English Math
0 90 80
1 80 85
# dfをnaddayに変換します。
p_n = np.array(df)

# 確認用
print(p_n)
  • 結果
    p_n:
    [ [90 80]
    [80 85] ]


一番初めにtestに入れたデータと全く同じものが出来上がりました。



<最終更新日:2021/09/10>
2021/09/10 投稿

NumPyのndarray その4 空のndarrayを作ってみよう

今日は、空のndarrayを作ってみたいと思います。

方法としては、
- 配列内(ndarray)の全要素を指定の数値で埋めて作る場合
- 初期化されていない空の配列(ndarray)を作る場合

の2種類があります。

配列内の全要素を数値で埋めて作るとは?

全てに「0」や「1」や「任意の数」を埋めて配列を作る場合です。

例として、2行3列の2次元配列をつくってみましょう。

import numpy as np
#0をうめる:i_0
i_0 = np.zeros([2,3])
#1をうめる:i_1
i_1 = np.ones([2,3])
#任意の数(今回は5にしてみます):i_5
i_5 = np.full([2,3],5)

結果:
i_0 = [ [0., 0., 0.],[0., 0., 0.] ]
i_1 = [ [1., 1., 1.],[1., 1., 1.] ]
i_5 = [ [5., 5., 5.],[5., 5., 5.] ]

任意の数については、Nan(欠損値)を入れることもできます。

i_nan = np.full([2,3],np.nan)

結果:
i_nan = [ [nan, nan, nan],[nan, nan, nan] ]

初期化されていない空の配列を作るとは?

空っぽの配列を作ります。
ただし注意したければいけない点が1つ。
もともとメモリ内に入っているランダムな値(未初期化の値)が入っています。

実際にみてみましょう。

i_emp = np.empty([2,3])

結果:
i_emp = [ [1.e-323, 2.e-323, 3.e-323],[2.e-323, 4.e-323, 6.e-323] ]

型を指定することも可能です。

i_emp_type = np.empty([2,3],dtype = int)

結果:
i_emp_type = [ [ 2, 4, 6],[ 4, 8, 12] ]

 どうやって使い分ける?

それぞれのメリットデメリットをまとめてみよう。

メリット デメリット
zeros()
ones()
fill()
など
入力したいデータが欠落していてもわかりやすい 初期化するのに時間がかかる
empty() 初期化処理が入らないため処理が早く終わる 入力データに欠落があるとどれが欠落したデータなのかわからない

このように、取扱データによって使い分けたほうがよいと思われます。

<最終更新日:2021/09/09>
2021/09/09 投稿