PandasにはSeriesと呼ばれるデータ構造があり、Pandasをマスターするにあたって基礎の基礎の構造です。今回はSeriesの作成から始まり基本的な使い方について解説します。
PandasはPythonでデータ分析や機械学習をするときに便利がライブラリです。Excelのような表計算ソフトを使わなくても表計算ができたり、スクレイピングにて集めたデータを表にまとめ、必要な部分をCSVに保存したり、いろんな応用が効きます。
そんな中、表形式ではなく1列切り抜いたデータ形式が今回解説するSeriesと呼ばれるデータ構造です。Pandasとは?Seriesとは?から、Seriesの基本的な操作までを1記事で網羅していきます。
最後まで読むことで、Pandasでできることのイメージが膨らむこと間違いなしです。今後データ分析をしたいとか、Pandasを使ってプログラムを作成したい人は最後まで是非読んでいってください。
それではやっていきましょう!
- Pandasでできること
- Seriesとは
- Seriesの作成方法
- Seriesの基本操作
Pandasとは? Seriesとは?
PandasはPythonでデータ分析をしたり、機械学習を行う上で欠かせないライブラリです。NumPyやmatplotlibなどと組み合わせたりすることでより高度なデータ分析をすることができます。
AIや機械学習についての学習をしたいと考えている人であれば、避けては通れないライブラリなのでしっかり理解していきましょう。
Pandasで主に扱うデータにはDataFrame型とSeries型、2つのデータ構造があります。
pandas.DataFrame() とか pandas.Series() といったコードを書いて作成しますが、DataFrameとSeriesの違いについては理解していないとデータをうまく扱うことができません。
DataFrame型は、2次元型のデータ構造で、一つの観測対象に当たって2つ以上の測定値があるデータ構造です。
例えば、1クラスの国数理社英5科目の点数データを分析したい場合、生徒Aという観測対象に対して、国語のテストの点数、数学の点数、、、と5つの測定値があるデータを分析したい時はDataFrame型を使います。
Series型は、1次元型のデータ構造で、1つの観測対象に1つの測定値が存在するデータのことです。例えば、英語のテストのみのデータを扱いたいときは、Seres型のデータ構造で事足ります。
DataFrame型から1行、あるいは1列取り出したものがSeries型ともいえます。今回はSeries型に絞って詳しく解説していきます。
Seriesとは?
Seriesとは1次元のデータ構造です。実際にPandasを使ってSeries型のデータを作成して出力したものを見た方がわかりやすいのでまずは作成したものを見てください。作成方法は後ほど触れます。
import pandas as pd
list = ["りんご","ぶどう","みかん","ばなな"]
pd.Series(data = list)
**出力結果**
0 りんご
1 ぶどう
2 みかん
3 ばなな
dtype: object
import pandas as pd でPandasを使います宣言をしておきます。
pd.Series(data = list)のように、pd.Series()引数に data = リスト を入れてあげることでSeriesの作成ができます。pd.Series()に入れる引数には主に、data以外にも index や name が存在します。
Seriesの行番号(インデックス)と値(データ)
Seriesには行番号(インデックス)と値(データ)から成り立っています。左の「0,1,2,3」をインデックスと呼び、「りんご、ぶどう、みかん、ばなな」をデータとか値と呼びます。
インデックスは自分で指定することで「0,1,2,3」意外に変更することができます。(変更方法は以下で詳しく説明します。)
Seriesの値の追加・変更 ・削除
Seriesの値を新たに追加したり、変更したり、削除する方法を解説します。
- Seriesのインデックス名の変更 👉 pd.Series(data = list , index = ["インデックス名"])
- Seriesの値追加 👉 Series["追加したいインデックス名"] = 追加する値
- Seriesの値の変更 👉 Series["変更したいインデックス名"] = 変更後の値
- Seriesの値の削除 👉 Series.drop(インデックス名)
Series インデックス名を変更する
import pandas as pd
list = ["りんご","ぶどう","みかん","ばなな"]
ser1 = pd.Series(data = list)#indexを変更することもできる。
print(ser1)
ser2 = pd.Series(data = list,index = ["a","b","c","d"])
print(ser2)
**出力結果**
0 りんご
1 ぶどう
2 みかん
3 ばなな
dtype: object
a りんご
b ぶどう
c みかん
d ばなな
dtype: object
ser1 には特にインデックス名を指定せずに作成したのでインデックスは「0,1,2,3」となっていますが、ser2 は引数に index = ["a","b","c","d"] を指定することでインデックス名が「a,b,c,d」となっています。
このように pd.Series() の引数に 「index = ["インデックス名"]」を格納することでインデックス名を指定できます。
注意点として、値の数とインデックス名の数が同じでないとエラーになります。今回の場合、果物の数は4つなのでインデックス名も4つ指定する必要があります。
Seriesの値を追加する
list = ["りんご","ぶどう","みかん","ばなな"]
index = ["a","b","c","d"]
ser = pd.Series(list,index)
print(ser)
#値を追加する。
ser["e"] = "いちご"
print(ser)
**出力結果**
a りんご
b ぶどう
c みかん
d ばなな
dtype: object
a りんご
b ぶどう
c みかん
d ばなな
e いちご
dtype: object
Seriesの値を変更する
Seriesにはインデックスと値で成り立っていますが、値も変更することができます。以下を見てみましょう。
list = ["りんご","ぶどう","みかん","ばなな"]
index = ["a","b","c","d"]
ser = pd.Series(list,index)
print(ser)
#Seriesに値を追加するには、["新たなindex名"] = 値
ser["d"] = "もも"
print(ser)
**出力結果**
a りんご
b ぶどう
c みかん
d ばなな
dtype: object
a りんご
b ぶどう
c みかん
d もも
dtype: object
出力結果を見てみると、インデックスd の値が「ばなな」から「もも」に変更されています。
Series["値を変更したいインデックス名"] = "変更後の値" で値を変更することができます。
今回の場合だと、ser["d"] = "もも" で「インデックスd の値を "もも" に変更」というコードです。
Seriesの値の削除 Series.drop()
Series不要な行を削除しましょう。削除するには Series.drop() を使います。今回は 「インデックス c の "いみかん"」を削除してみましょう。
コードは以下です。
#Seriesから値を削除する方法 👉 Series.drop["消去するインデックス名"]
list = ["りんご","ぶどう","みかん","ばなな"]
index = ["a","b","c","d"]
ser = pd.Series(list,index)
print(ser)
#値を追加する。
ser["e"] = "いちご"
print(ser)
#削除
ser = ser.drop("c")
print(ser)
**出力結果**
a りんご
b ぶどう
c みかん
d ばなな
dtype: object
a りんご
b ぶどう
c みかん
d ばなな
e いちご
dtype: object
a りんご
b ぶどう
d ばなな
e いちご
dtype: object
Seriesの作成
Seriesにはさまざまな作成方法があるので、そのうちの基礎的なものを紹介しておきます。
- リストからの作成
- 辞書からの作成
- ndarrayからの作成
- DataFrameからの作成
Seriesをリストから作成
Seriesの作成方法の一つはリストからの作成です。pd.Series() の引数にリストを格納することで、Seriesを作成することができます。
実際に出力結果を見てみましょう。
list = ["りんご","ぶどう","みかん","ばなな"]
index = ["a","b","c","d"]
ser = pd.Series(list,index)
print(ser)
**出力結果**
a りんご
b ぶどう
c みかん
d ばなな
dtype: object
リストは list = ["りんご","ぶどう","みかん","ばなな"] のように リスト名 =["a","b",・・・] とすることで作成することができます。
そして pd.Series() の引数に リスト名を指定することで Series を作成することができます。
ちなみに冒頭で説明した時には、pd.Series(data = list , index = ["a","b","c","d"])と引数の中で「data = リスト名」としていましたが、「data =」や「index = 」は省略することができます。
Seriesを辞書から作成
Seriesの作成方法は、pd.Series() の引数に辞書を格納することでSeriesを作成することができます。
実際に出力結果を見てみましょう。
#リスト型からではなく辞書型からの作成も可能
dict = {
"a":"しゃけ",
"b":"うめ",
"c":"ツナマヨ"
}
print(pd.Series(dict))
**出力結果**
a しゃけ
b うめ
c ツナマヨ
dtype: object
辞書は
dict = {
"a":"しゃけ",
"b":"うめ",
"c":"ツナマヨ"
}
のように、 辞書名 = { "key名": "value名"} で作成することができます。
作成した辞書を引数に指定してあげることでSeriesを作成することができます。辞書から作成した場合、key値がインデックス名になるので、引数にインデックスを指定する必要がありません。
SeriesをNumPyで作成した ndarray から作成
Seriesの作成には、リストからの作成、辞書からの作成以外にNumPyで作成したndarrayからも作成することができます。ndarrayとは、NumPyから作成されたデータ構造の名前で、リストに似た形のデータ構造です。
引数に data = ndarray を格納することでSeriesの作成が可能です。
#NumPyによって作成したndarrayからSeries作成
#NumPyを使う宣言
import numpy as np
#ndarrayを作成して arr に格納
arr = np.array([11, 22, 33])
print(type(arr))
index = ["a","b","c"]
pd.Series(data = arr, index = index)
**出力結果**
<class 'numpy.ndarray'>
a 11
b 22
c 33
dtype: int64
ndarrayとリストの大きな違いは、リストには["りんご",11,True]のようにstr型やint型など型の違う要素を格納できがますが、ndarrayには同一の型しか入れられないことなどがあります。
ただ、type() でデータ型を確認すると numpy.ndarray と表示されていますね。
これで pd.Series() の引数に data = ndarray を入れてあげることでSeiresの作成ができます。
DataFrameの一部からSeiresを作成
Pandasで作成できるデータ構造には DataFrame と Series がありますが、DataFrame から Seriesを作成することもできます。(作成というよりは、DataFrame の中から切り取る感覚に近いですが...)
#DataFrameの一部の列を抽出し、Seriesを作成することもできます。
list=[[1,2,3], [21,22,23], [31,32,33]]
index = ["Row1", "Row2", "Row3"]
columns =["Col1", "Col2", "Col3"]
df = pd.DataFrame(data=list, index=index, columns=columns)
print(df)
ser = df["Col2"]
print(ser)
**出力結果**
Col1 Col2 Col3
Row1 1 2 3
Row2 21 22 23
Row3 31 32 33
Row1 2
Row2 22
Row3 32
Name: Col2, dtype: int64
DataFrameは行と列、縦横の表形式で表される2次元からできるデータ構造です。
列を一つ抜き取ることでSeriesを作成することができます。pd.DataFrame() にてDataFrameを作成することができます。その後、DataFrame["カラム名"] でSeriesを抜き取ることができます。
今回は["Col2"]を指定してあげることで、カラムCol2の列を指定してSeries型として出力することができます。
ちなみに、index = ["Row1", "Row2", "Row3"] や columns =["Col1", "Col2", "Col3"] のように格納したリストを引数に取ることで インデックス名やカラム名 を指定することもできます。初期値では 0,1,2 です。
Seriesの演算
Seriesの演算と結合についてもよく使うので紹介しておきます。
Seriesの演算
同じインデックス名に格納されている値がint型であれば、Series同士で演算することができます。
以下のコードで詳しく見ていきましょう。
#同じインデックス同士で演算もできるよ!
list1 = [1, 2, 3, 4, 5]
list2 = [10, 20, 30, 40, 50]
index1 = ["R1", "R2", "R3", "R4", "R5"]
ser1 = pd.Series(data = list1, index = index1)
ser2 = pd.Series(data = list2, index = index1)
print(ser1)
print(ser2)
print(ser1 + ser2)
print(ser2 - ser1)
**出力結果**
R1 1
R2 2
R3 3
R4 4
R5 5
dtype: int64
R1 10
R2 20
R3 30
R4 40
R5 50
dtype: int64
R1 11
R2 22
R3 33
R4 44
R5 55
dtype: int64
R1 9
R2 18
R3 27
R4 36
R5 45
dtype: int64
ser1 と ser2 の2つ Series を作成しそれぞれに同じインデックス名を付けています。
ser1 + ser2 の演算を行うと、 ser1 の インデックスR1 の値 「1」と ser2 のインデックスR1の値「10」を足して「11」、R2同士の和である「22」、、、と同じインデックス名同士の和が新たにSeriesとして出力します。
差も同じように作成することができます。
同じインデックス名同士であれば同じように演算ができるのですが、異なるインデックス名がある場合はどうなるのでしょうか。
以下を見てみましょう。
#インデックス名が違うとどうなるの?
list1 = [1, 2, 3, 4, 5]
list2 = [10, 20, 30, 40, 50]
index1 = ["R1", "R2", "R3", "R4", "R5"]
index2 = ["R3", "R4", "R5", "R6", "R7"]
ser1 = pd.Series(data = list1, index = index1)
ser2 = pd.Series(data = list2, index = index2)
print(ser1)
print(ser2)
print(ser1 + ser2)
print(ser2 - ser1)
**出力結果**
R1 1
R2 2
R3 3
R4 4
R5 5
dtype: int64
R3 10
R4 20
R5 30
R6 40
R7 50
dtype: int64
R1 NaN
R2 NaN
R3 13.0
R4 24.0
R5 35.0
R6 NaN
R7 NaN
dtype: float64
R1 NaN
R2 NaN
R3 7.0
R4 16.0
R5 25.0
R6 NaN
R7 NaN
dtype: float64
ser1 にはあって ser2 にあるインデックスだと、演算結果は NaN となります。NaNは値が空という意味です。
また、int型 から float型 にかわります。
Seriesの結合
Seriesの結合とは、Series 1 と Series2 の2つを組み合わせることで、Seriesの結合には append と concat 2種類の結合方法があります。
結合とは、Series1 の下に Series2 をくっつけるイメージです。
詳しく見ていきましょう。
- append を使った結合
- concat を使った結合
Seriesの結合①:append
Seriesの結合方法一つ目は append を使った結合です。appendを使った結合は、 Series.append(結合したいSeries)で結合することができます。
実際にコードを出力してみましょう。
#結合append
list1 = [1,2,3,4,5]
list2 = [10,11,12]
ser1 = pd.Series(list1)
ser2 = pd.Series(list2)
print(ser1)
ser3 = ser1.append(ser2)
print(ser3)
ser3 = ser1.append(ser2,ignore_index=True)
print(ser3)
**出力結果**
0 1
1 2
2 3
3 4
4 5
dtype: int64
0 1
1 2
2 3
3 4
4 5
0 10
1 11
2 12
dtype: int64
0 1
1 2
2 3
3 4
4 5
5 10
6 11
7 12
dtype: int64
Series.append() の引数には、主に Series と ignore_index を取ることができます。 Series は結合したい Series なのでわかりやすいと思いますが、 ignore_index はインデックス名を変更するかそのままにするかを指定することができます。
例えば、先に出力した ser1 は インデックス番号「0、1、2、3、4」の 5つですが、 ser1.append(ser2)で結合を行い ser3 を出力すると、「0,1,2,3,4,0,1,2」と ser1 の下に ser2 が結合されています。
ser1.append(ser2,ignore_index=True) のように引数に 「ignore_index=True」をとることで先では「0,1,2,3,4,0,1,2」とインデックス名は ser2 で設定したもののままだったのに対して 「0,1,2,3,4,5,6,7」と新たにインデックス名を設定し直しています。
Seriesの結合②:concat
次に concat を使った結合方法を紹介します。
list1 = [1,2,3,4,5]
list2 = [10,11,12]
ser1 = pd.Series(list1)
ser2 = pd.Series(list2)
print(ser1)
ser3 = pd.concat([ser1,ser2],ignore_index=False)
print(ser3)
ser4 = pd.concat([ser1,ser2],ignore_index=True)
print(ser4)
**出力結果**
0 1
1 2
2 3
3 4
4 5
0 10
1 11
2 12
dtype: int64
0 1
1 2
2 3
3 4
4 5
5 10
6 11
7 12
dtype: int64
concat を使った結合では、Pandas.concat(結合したいSeries) で結合します。
今回の場合は pd.concat([ser1,ser2],ignore_index=False) とすることで ser1 と ser2 を結合でき、appendを使った時と同じ出力結果になっています。
また、appendの時と同じように、ignore_index を引数に取ることもできますので、ほとんどappendと同じ使い方です。
Seriesの並び替え(ソート)
Seriesの使い道として値を大きい順に並び替えたり、平均値や最大値を出力したりすることもできます。
例では5つの値のみなので見ればわかりますが、実際の現場では1列に数百、数千ものデータを扱うことも少なくないので並び替えや統計処理の方法は必ずマスターしましょう。
Seriesの並び替え(ソート)
Seriesの並び替えには、インデックス名を基準とした並び替えと、値を基準とした並び替えの2種類あります。それぞれ sort_index , sort_value を用いて並び替えを行います。
#Seriesの並び替え
student_pt = [70,72,84,67,95]
index = ["生徒A","生徒B","生徒C","生徒D","生徒E"]
ser = pd.Series(data = student_pt , index = index)
print(ser)
#インデックスを基準に並び替え
ser = ser.sort_index(ascending=False)
print(ser)
#値を基準に並び替え
ser = ser.sort_values(ascending=False)
print(ser)
**出力結果**
生徒A 70
生徒B 72
生徒C 84
生徒D 67
生徒E 95
dtype: int64
生徒E 95
生徒D 67
生徒C 84
生徒B 72
生徒A 70
dtype: int64
生徒E 95
生徒C 84
生徒B 72
生徒A 70
生徒D 67
dtype: int64
生徒5人のテストの点数をSeriesとして作成してみました。
Series.sort_index(ascending = True/False) でインデックス名を基準に並び替えができます。引数に「ascending = True」 を設定すると昇順、「ascending = False」 を設定すると降順に並び替えます。
インデックス名を基準に並び替えているので 生徒A〜生徒E の順だった Series を ser = ser.sort_index(ascending=False) で降順に並び替えると 生徒E〜生徒Aに並び替えられています。
Series.sort_values(ascending=True/False) で値を基準に並び替えることもできます。今回で言うとテストの点数順に並び替えることができます。
ser.sort_values(ascending=False) で値が大きい順に並び替えできています。
Seriesの統計処理
Seriesの統計処理を行うこともできます。統計処理とは具体的に、平均値や最大値、標準偏差を求めたりすることができます。いよいよデータ分析っぽくなってきました。
統計処理を応用することでグラフを作成したり、機械学習に必要なデータの前処理を行うことにもつながってきますので、しっかりマスターしておきましょう。
Series.describe() で統計データ取得
Series.describe() を使うと統計情報が一括で取得することができます。
一括で取得した結果が以下です。
#統計情報の取得
student_pt = [70,72,84,67,95]
index = ["生徒A","生徒B","生徒C","生徒D","生徒E"]
ser = pd.Series(data = student_pt , index = index)
print(ser)
describe = ser.describe()
print(describe)
**出力結果**
生徒A 70
生徒B 72
生徒C 84
生徒D 67
生徒E 95
dtype: int64
count 5.000000
mean 77.600000
std 11.674759
min 67.000000
25% 70.000000
50% 72.000000
75% 84.000000
max 95.000000
dtype: float64
取得できた統計データを見てみましょう。
count | データの個数 |
mean | 平均値 |
std | 標準偏差 |
min | 最小値 |
25% | 第一四分位数 |
50% | 中央値 |
75% | 第三四分位数 |
max | 最大値 |
統計データはどんな分析を行うかによって使うデータが異なりますが、Series.describe() で取得できる統計データを利用することは多いのでとても便利な関数です。
また、平均だけ取得したい場合などは、Series.mean() や Series.std()とすることで平均値や標準偏差だけを取得することもできます。
しっかり覚えておきましょう。
まとめ
今回は、Pandas入門編の2回目で、Seriesの基本的操作について解説していきました。
データ分析を行う上で、Pandasは必修ライブラリです。その中でもSeriesとDataFrameの構造の違いや基本的な操作を行うことは基本中の基本として必ずマスターしてください。
これからAIを作りたいとか、機械学習を勉強したいとか、データサイエンティストになりたいと考えている人であれば当記事で紹介した内容は必ず役に立つでしょう。
当記事でも十分なほどデータ分析についての解説を行っていますが、「お金をかけた方が全力でできる!」といった方にはプログラミングスクールがおすすめです。
- プログラミングスクールはたくさんあって選べない。
- プログラミングスクールに興味はあるけどなかなか踏み出せない。
- 独学に限界を感じている
こんな方は、ぜひ一度こちらの記事を読んでプログラミングスクールについて知ってください!知った上で「選択するのか、しないのか」を決めてください。
Pythonを習得することで、Google画像検索から画像を取得するだけでなく、メルカリの商品情報を取得したり、Twitterのbotを作成したりとさまざまなことができます。作りたいものがあるのであれば是非Pythonを習得しましょう!
爆速でPythonを習得するにはプログラミングスクールなどを有効に活用するのが一番です。ただプログラミングスクールはたくさんあってどこがいいのかわからないという人のために以下の記事で紹介しているので是非参考にしてください。
また、プログラミングを習得することで転職や、副業、フリーランスなどの働き方に選択肢が広がりますので、将来に不安を抱えていたり、本当は今よりもやりたいことがある人は、キャリア相談を受けることで今の自分は何をすべきなのかが見えてきます。
キャリア相談については以下の記事でまとめていますので、ぜひご活用ください。