ヒトリ歩き

愚痴とかいろいろ書きます

データ分析の第一歩:Pandasを使ったデータ型と操作

streamlitでも出てきたpandasを使ったことがないので、基本的な部分をやってみる。
これを使いこなして、品質データもサクッと集計したり消化スケジュールもサクッとグラフ化して雑務の工数を減らしたい。

pandasのデータ型

Pandasのデータ型としてはSeriesとDataFrameという2つのものがある。

Series

1次元データ構造と言われる1列のみのデータ型。

s = [1, 2, 3, 4, 5]
series = pd.Series(s)
print(series)

左側の番号が行ラベルと言われるindex indexを指定しない場合、0から開始になる。

0    1
1    2
2    3
3    4
4    5
dtype: int64

indexを指定する場合、indexパラメータに値を設定。

s = [1, 2, 3, 4, 5]
index = ["a", "b", "c", "d", "e"]
series = pd.Series(s, index=index)
print(series)

・出力結果
a    1
b    2
c    3
d    4
e    5

DataFrame

2次元データ構造と言われるデータ構造。 2次元配列で表すデータよりは、Excelで作る表をイメージするとわかりやすい。

data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
]
column = ["name", "age", "m/f", "y of experience", "score"]
df = pd.DataFrame(data=data, columns=column)
print(df)

出力結果はこうなる。

        0   1       2  3    4
0  tanaka  20  female  1  600
1  suzuki  30    male  8  492
2  tanaka  23    male  3  890
3    sato  28    male  4  833

DataFrameは、indexとcolumnsがある。 indexを指定できたように、columnsも列名を指定できる。

data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
]
column = ["name", "age", "m/f", "y of experience", "score"]
df = pd.DataFrame(data=data, columns=column)
print(df)

・出力結果
     name  age     m/f  y of experience  score
0  tanaka   20  female                1    600
1  suzuki   30    male                8    492
2  tanaka   23    male                3    890
3    sato   28    male                4    833

データの取得

データの取得方法にはいくつか方法がある。

特定の列または行を取得

pandasは、[]にキーを入力すると列名と判断し、スライスを入力すると行ラベルと判断して処理する。

www.sejuku.net

import pandas as pd

# DataFrame
# 2次元データ構造
data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
]
column = ["name", "age", "m/f", "y of experience", "score"]
df = pd.DataFrame(data=data, columns=column)
print(df)

# 特定の列を取得
print("ageカラムを取得")
print(df["age"])

# 特定の行を取得
print("3行目を取得")
print(df[2:3])

# 実行結果
ageカラムを取得
0    20
1    30
2    23
3    28
Name: age, dtype: int64
3行目を取得
     name  age   m/f  y of experience  score
2  tanaka   23  male                3    890

特定の列と行の取得

locを使用した列と行の取得は列名と行名を使用できる。

import pandas as pd

# DataFrame
# 2次元データ構造
data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
    ["takano", None, "male", 20, 234],
]
column = ["name", "age", "m/f", "y of experience", "score"]
index = ["0001", "0002", "0003", "0004", "0005"]
df = pd.DataFrame(data=data, columns=column, index=index)
print(df)

# 特定の列と行を取得
print("loc関数で取得")
print(df.loc["0003", "age":"m/f"])
print(df.loc["0004":])
# 実行結果
loc関数で取得
age    23.0
m/f    male
Name: 0003, dtype: object
        name   age   m/f  y of experience  score
0004    sato  28.0  male                4    833
0005  takano   NaN  male               20    234

ilocの場合は、列名や行名は使用できない。 インデックス番号を使用する必要がある。

import pandas as pd

# DataFrame
# 2次元データ構造
data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
    ["takano", None, "male", 20, 234],
]
column = ["name", "age", "m/f", "y of experience", "score"]
index = ["0001", "0002", "0003", "0004", "0005"]
df = pd.DataFrame(data=data, columns=column, index=index)
print(df)

# 特定の列と行を取得
print("ilocを使用")
print(df.iloc[2:, 1:3])
print(df.iloc[3:])
ilocを使用
       age   m/f
0003  23.0  male
0004  28.0  male
0005   NaN  male
        name   age   m/f  y of experience  score
0004    sato  28.0  male                4    833
0005  takano   NaN  male               20    234

locとilocで同じような使い方だが、行列のスライスの指定の結果が異なる。 locの場合は、スライスの最後のインデックスが含まれるが、ilocの場合は、スライスの最後のインデックスは含まれない。

先頭と末尾の取得

先頭のデータを取得する際は、head関数を使用する。 また、末尾のデータを取得する場合は、tail関数を使用する。 ともにデフォルトは5件取得。 ここでは、2を指定することで、2件取得している。

import pandas as pd
# DataFrame
# 2次元データ構造
data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
    ["takano", None, "male", 20, 234],
]
column = ["name", "age", "m/f", "y of experience", "score"]
index = ["0001", "0002", "0003", "0004", "0005"]
df = pd.DataFrame(data=data, columns=column, index=index)

# 先頭と末尾を取得
print("= 先頭 ==========")
print(df.head(2))

print("= 末尾 ==========")
print(df.tail(2))
# 実行結果
= 先頭 ==========
        name   age     m/f  y of experience  score
0001  tanaka  20.0  female                1    600
0002  suzuki  30.0    male                8    492
= 末尾 ==========
        name   age   m/f  y of experience  score
0004    sato  28.0  male                4    833
0005  takano   NaN  male               20    234

条件指定での行取得

query関数を使用することで、データベースを検索するように条件を指定してデータを取得できる。

import pandas as pd

# DataFrame
# 2次元データ構造
data = [
    ["tanaka", 20, "female", 1, 600],
    ["suzuki", 30, "male", 8, 492],
    ["tanaka", 23, "male", 3, 890],
    ["sato", 28, "male", 4, 833],
    ["takano", None, "male", 20, 234],
]
column = ["name", "age", "m/f", "y of experience", "score"]
index = ["0001", "0002", "0003", "0004", "0005"]
df = pd.DataFrame(data=data, columns=column, index=index)

# 条件指定
print("== ageが30より小さい行を取得 ======")
print(df.query("age < 30"))
print("== nameがtanakaの行を取得 ======")
print(df.query("name == 'tanaka'"))
print("== nameがtanakaかつageが23の行を取得 ======")
print(df.query("name == 'tanaka' and age == 23"))
# 実行結果
== ageが30より小さい行を取得 ======
        name   age     m/f  y of experience  score
0001  tanaka  20.0  female                1    600
0003  tanaka  23.0    male                3    890
0004    sato  28.0    male                4    833
== nameがtanakaの行を取得 ======
        name   age     m/f  y of experience  score
0001  tanaka  20.0  female                1    600
0003  tanaka  23.0    male                3    890
== nameがtanakaかつageが23の行を取得 ======
        name   age   m/f  y of experience  score
0003  tanaka  23.0  male                3    890

列と行の追加

列を追加する場合、[列名]=値またはassign関数を使用する。 assign関数を使用した場合、新しいDataFrameのオブジェクトを返す。 行を追加する場合、loc[行名] = 値で追加できる。 また、concat関数でDataFrame同士を連結する方法もある。

import pandas as pd

data = [["tanaka", 20, "female", 1, 600], ["suzuki", 30, "male", 8, 492]]
column = ["name", "age", "m/f", "y of experience", "score"]
df = pd.DataFrame(data=data, columns=column)
print("== 追加前 ================")
print(df)
print("== 列を追加1 ==============")
df["like"] = ["movie", "cook"]
print(df)
print("== 列を追加2 ==============")
df = df.assign(food=["sushi", "apple"])
print(df)
print("== 行を追加1 ==============")
df.loc[2] = ["yamada", 40, "male", 20, 500, "cycle", "beaf"]
print(df)

最後に

pandasの基本的な操作をやってみた。 集計とかその辺をもう少しやってみて、品質データの分析を簡単に集計できるようになったら、嬉しいな。

参考

qiita.com

qiita.com

qiita.com