Pandas (パンダス) は、Python でデータ分析やデータ加工を行うための最も人気のあるオープンソースライブラリです。CSV のような表形式のデータを、シンプルなコードで高速に処理・分析できます。今回は Pandas の基本的な使い方を簡単に説明します。
一般的な Python 環境では、コマンドプロンプト (Windows) またはターミナル (Mac / Linux) を開き、以下のコマンドを実行します。
(.venv) $ pip install pandas
$ pip freeze | grep pandas pandas==3.0.5
コマンド pip は仮想環境下で実行する必要があります。仮想環境については拙作のページ 仮想環境とパッケージ を参考にしてください。M.Hiroi がインストールしたのは ver 3.0.5 (2026 年 8 月時点) です。
Pandas を使うときは、最初に必ず Pandas をインポートしてください。慣例として pd という短い名前をつけて呼び出すのが一般的です。
>>> import numpy as np >>> import pandas as pd >>> print(pd.__version__) 3.0.5
Pandas には 2 つの中心的なデータ構造があります。
シリーズはコンストラクタ Series() で生成します。引数には Python のリストや NumPy の配列 (ndarray) などを渡します。簡単な実行例を示します。
>>> import numpy as np >>> import pandas as pd >>> pd.Series([1, 3, 5, 7, 9]) 0 1 1 3 2 5 3 7 4 9 dtype: int64 >>> pd.Series(np.array([1, 3, 5, 7, 9])) 0 1 1 3 2 5 3 7 4 9 dtype: int64 >>> pd.Series(np.arange(0, 10, 2)) 0 0 1 2 2 4 3 6 4 8 dtype: int64
左側の 0 から始まる数値は行番号 (添字) です。デフォルトではリストや配列と同じく整数値になります。Series() のキーワード引数 index で数値以外の名前を指定することができます。行番号を使ってシリーズの要素にアクセスするのはリストや配列と同じです。
>>> a = pd.Series([1, 3, 5, 7, 9])
>>> a
0 1
1 3
2 5
3 7
4 9
dtype: int64
>>> a[0]
np.int64(1)
>>> a[4]
np.int64(9)
>>> b = pd.Series([1, 3, 5, 7, 9], index = list('abcde'))
>>> b
a 1
b 3
c 5
d 7
e 9
dtype: int64
>>> b['a']
np.int64(1)
>>> b.e
np.int64(9)
名前を指定する場合、'シリーズ[名前]' または 'シリーズ + . + 名前' でアクセスすることができます。
また、Python の辞書を使ってシリーズを生成することもできます。この場合、辞書のキーがシリーズの行名になります。簡単な実行例を示します。
>>> c = pd.Series({'foo': 10, 'bar': 20, 'baz': 30})
>>> c
foo 10
bar 20
baz 30
dtype: int64
>>> c['foo']
np.int64(10)
>>> c.baz
np.int64(30)
データフレームはファイル (CSV 形式など) からデータを読み込んで生成するのが一般的で、Pandas にはデータ形式に対応したファイルのアクセス関数 (メソッド) が用意されています。そのほかにも、コンストラクタ DataFrame() でデータフレームを生成することができます。
一番簡単な方法は DataFrame() に 2 次元配列 (リスト) を渡すことです。次の例を見てください。
>>> pd.DataFrame([[1,2,3],[4,5,6]])
0 1 2
0 1 2 3
1 4 5 6
>>> pd.DataFrame(np.random.rand(2, 3))
0 1 2
0 0.491888 0.501126 0.305116
1 0.353727 0.771552 0.732977
2 行 3 列のデータフレームを生成します。Python のリストであれば、入れ子にすることで 2 次元配列を表すことができます。rand() は NumPy に用意されている関数で、要素が乱数の配列を生成します。データフレームは行だけではなく、列にも番号が付くことに注意してください。DataFrame() のキーワード引数 index で行名を、columns で列名を指定することができます。
>>> pd.DataFrame(np.random.rand(3, 4), index = list('XYZ'), columns = list('ABCD'))
A B C D
X 0.670507 0.797924 0.355502 0.568230
Y 0.299877 0.832172 0.172603 0.213596
Z 0.160879 0.655925 0.215070 0.510483
シリーズと同様に辞書からデータフレームを生成することもできます。
>>> df = pd.DataFrame(
{'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'Score': [85.5, 92.0, 78.0]})
>>> df
Name Age Score
0 Alice 25 85.5
1 Bob 30 92.0
2 Charlie 35 78.0
この場合、辞書のキーが列名になります。
データフレーム df の要素は df[列][行] でアクセスすることができます。
>>> df['Name'][0] 'Alice' >>> df['Score'][2] np.float64(78.0)
この他に、データフレーム df の情報は以下の関数 (メソッド) や属性で求めることができます。
>>> df
Name Age Score
0 Alice 25 85.5
1 Bob 30 92.0
2 Charlie 35 78.0
>>> len(df)
3
>>> df.size
9
>>> df.index
RangeIndex(start=0, stop=3, step=1)
>>> list(df.index)
[0, 1, 2]
>>> df.columns
Index(['Name', 'Age', 'Score'], dtype='str')
>>> list(df.columns)
['Name', 'Age', 'Score']
>>> df.values
array([['Alice', 25, 85.5],
['Bob', 30, 92.0],
['Charlie', 35, 78.0]], dtype=object)
>>> df.info()
<class 'pandas.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Name 3 non-null str
1 Age 3 non-null int64
2 Score 3 non-null float64
dtypes: float64(1), int64(1), str(1)
memory usage: 204.0 bytes
列は df[列], df.列名 で取り出すことができます。返り値はシリーズになります。また、リストで複数の列名を指定して、列を取り出すこともできます。この場合、返り値はデータフレームになります。
>>> df['Name']
0 Alice
1 Bob
2 Charlie
Name: Name, dtype: str
>>> df.Name
0 Alice
1 Bob
2 Charlie
Name: Name, dtype: str
>>> df[['Name', 'Age']]
Name Age
0 Alice 25
1 Bob 30
2 Charlie 35
行の取得は df.loc[行名] または df.iloc[行番号] を使います。loc は行名を、iloc は行番号を指定します。返り値はシリーズになります。また、リストで複数の行を指定する、もしくは、スライスのように : を使って指定した行を取り出すこともできます。この場合、返り値はデータフレームになります。
>>> df.iloc[0]
Name Alice
Age 25
Score 85.5
Name: 0, dtype: object
>>> df.iloc[[0, 2]]
Name Age Score
0 Alice 25 85.5
2 Charlie 35 78.0
>>> df.iloc[:]
Name Age Score
0 Alice 25 85.5
1 Bob 30 92.0
2 Charlie 35 78.0
>>> df.iloc[1:3]
Name Age Score
1 Bob 30 92.0
2 Charlie 35 78.0
このほかにも、loc[行番号, 列名], iloc[行番号, 列番号] のように、列も一緒に指定することができます。
>>> df.loc[0, 'Name'] 'Alice' >>> df.loc[2, 'Score'] np.float64(78.0) >>> df.loc[:, 'Score'] 0 85.5 1 92.0 2 78.0 Name: Score, dtype: float64 >>> df.iloc[1, 1] np.int64(30) >>> df.iloc[1, 2] np.float64(92.0) >>> df.iloc[:, 0] 0 Alice 1 Bob 2 Charlie Name: Name, dtype: str
メソッド df.head(N) はデータフレームの先頭 N 行を表示します。メソッド df.tail(N) はデータフレームの末尾 N 行を表示します。どちらのメソッドも N を省略すると 5 行表示します。
>>> df.head(2)
Name Age Score
0 Alice 25 85.5
1 Bob 30 92.0
>>> df.tail(2)
Name Age Score
1 Bob 30 92.0
2 Charlie 35 78.0
df[indexing] の indexing に Bool 型のシーケンスを渡すと、True に対応する行を取り出すことができます。
>>> df
Name Age Score
0 Alice 25 85.5
1 Bob 30 92.0
2 Charlie 35 78.0
>>> df[[True, False, True]]
Name Age Score
0 Alice 25 85.5
2 Charlie 35 78.0
>>> df[[False, True, False]]
Name Age Score
1 Bob 30 92.0
シリーズや NumPy の配列に述語を適用すると、Bool 型のシーケンスを得ることができます。
>>> df['Age'] >= 30
0 False
1 True
2 True
Name: Age, dtype: bool
>>> df[df['Age'] >= 30]
Name Age Score
1 Bob 30 92.0
2 Charlie 35 78.0
行全体ではなく、列名を指定して値を取り出すこともできます。
>>> df[df['Age'] >= 30]['Name'] 1 Bob 2 Charlie Name: Name, dtype: str >>> df.loc[df['Age'] >= 30, 'Name'] 1 Bob 2 Charlie Name: Name, dtype: str
特定の文字を含む行を取り出したい場合は関数 str.contains() を使います。
>>> df[df['Name'].str.contains('Al')]
Name Age Score
0 Alice 25 85.5
>>> df[df['Name'].str.contains('i')]
Name Age Score
0 Alice 25 85.5
2 Charlie 35 78.0
最初の例は列 Name の要素 (文字列) で、Al を含んでいる行を取り出します。次の例は i を含んでいる行を取り出します。
メソッド query() は、条件式 (クリエ式) を文字列で記述して、条件式を満たす行を取り出します。
>>> df.query('Age >= 30')
Name Age Score
1 Bob 30 92.0
2 Charlie 35 78.0
>>> df.query('Age >= 30 and Score >= 80')
Name Age Score
1 Bob 30 92.0
>>> df.query('Age >= 30 and Score <= 80')
Name Age Score
2 Charlie 35 78.0
>>> df.query('Name == "Alice"')
Name Age Score
0 Alice 25 85.5
クリエ式の中で、列名、比較演算子、論理演算子 (and, or) はそのまま利用することができます。文字列と比較するときは、中の文字列を囲むクォーテーションを変更してください。
クリエ式の中で Python の変数を参照する場合、変数名の前に @ を付けるか、f-string を使って変数展開します。
>>> low_age = 30
>>> df.query('Age >= @low_age')
Name Age Score
1 Bob 30 92.0
2 Charlie 35 78.0
>>> df.query(f'Age >= {low_age}')
Name Age Score
1 Bob 30 92.0
2 Charlie 35 78.0
クリエ式式の中では in, not in 演算子を使うことができます。
>>> age_list = [25, 30]
>>> df.query(f'Age in @age_list')
Name Age Score
0 Alice 25 85.5
1 Bob 30 92.0
>>> df.query(f'Age not in @age_list')
Name Age Score
2 Charlie 35 78.0
クリエ式の中で文字列を操作する関数 (str.contains() など) を呼び出すこともできます。
>>> df.query('Name.str.contains("A")')
Name Age Score
0 Alice 25 85.5
>>> df.query('Name.str.contains("i")')
Name Age Score
0 Alice 25 85.5
2 Charlie 35 78.0
データフレーム df の末尾 (右側) に新しい列を追加するのは簡単です。
>>> dfa = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
>>> dfa
A B
0 1 4
1 2 5
2 3 6
>>> dfa['C'] = [7, 8, 9]
>>> dfa
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> dfa['D'] = 10
>>> dfa
A B C D
0 1 4 7 10
1 2 5 8 10
2 3 6 9 10
>>> dfb = dfa.assign(E = [11, 12, 13])
>>> dfb
A B C D E
0 1 4 7 10 11
1 2 5 8 10 12
2 3 6 9 10 13
>>> dfa
A B C D
0 1 4 7 10
1 2 5 8 10
2 3 6 9 10
任意の位置に新しい列を挿入したい場合はメソッド insert() を使います。
>>> dfa
A B C D
0 1 4 7 10
1 2 5 8 10
2 3 6 9 10
>>> dfa.insert(0, 'E', 11)
>>> dfa
E A B C D
0 11 1 4 7 10
1 11 2 5 8 10
2 11 3 6 9 10
>>> dfa.insert(3, 'F', [12, 13, 14])
>>> dfa
E A B F C D
0 11 1 4 12 7 10
1 11 2 5 13 8 10
2 11 3 6 14 9 10
insert() は df を破壊的に修正します。
新しい列名ではなく、既存の列名を指定すると、その列の値を書き換えることができます。
>>> dfa = pd.DataFrame({'A': [1, 2, 3],'B': [4, 5, 6], 'C': [7, 8, 9]})
>>> dfa
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> dfa['B'] = 0
>>> dfa
A B C
0 1 0 7
1 2 0 8
2 3 0 9
>>> dfa['C'] =[11, 12, 13]
>>> dfa
A B C
0 1 0 11
1 2 0 12
2 3 0 13
>>> dfa.assign(B = 100)
A B C
0 1 100 11
1 2 100 12
2 3 100 13
>>> dfa
A B C
0 1 0 11
1 2 0 12
2 3 0 13
条件に応じて値を書き換えたい場合は loc を使うと簡単です。
条件式を満たす行の列名の値を value に書き換えます。簡単な実行例を示しましょう。
>>> dfa A B C 0 1 4 7 1 2 5 8 2 3 6 9 >>> dfa.loc[dfa['B'] % 2 == 0, 'C'] = 0 >>> dfa A B C 0 1 4 0 1 2 5 8 2 3 6 0 >>> dfa.loc[dfa['B'] % 2 != 0, 'B'] = 1 >>> dfa A B C 0 1 4 0 1 2 1 8 2 3 6 0
条件式の真偽に応じて値を書き換えたい場合は NumPy の関数 where() を使うと簡単です。
np.where() は結果を格納した配列 (ndarray) を返すので、データフレームを書き換えたい場合は返り値を代入してください。
>>> dfa A B C 0 1 4 0 1 2 1 8 2 3 6 0 >>> np.where(dfa['A'] % 2 == 0, 'even', 'odd') array(['odd', 'even', 'odd'], dtype='<U4') >>> dfa['D'] = np.where(dfa['A'] % 2 == 0, 'even', 'odd') >>> dfa A B C D 0 1 4 0 odd 1 2 1 8 even 2 3 6 0 odd
このほかに、Pandas には where() と mask() というメソッドがあり、条件に応じて列の値を置き換えることができます。
>>> df = pd.DataFrame({'A': [1,2,-1,3,4,-2,5,6]})
>>> df
A
0 1
1 2
2 -1
3 3
4 4
5 -2
6 5
7 6
>>> df['A'].where(df['A'] >= 0)
A
0 1.0
1 2.0
2 NaN
3 3.0
4 4.0
5 NaN
6 5.0
7 6.0
>>> df['A'].mask(df['A'] < 0)
A
0 1.0
1 2.0
2 NaN
3 3.0
4 4.0
5 NaN
6 5.0
7 6.0
del と drop() は列を削除します。
drop() は columns で指定した列を削除した新しいデータフレームを返します。元のデータフレームを直接書き換える場合は inplace=True を指定します。del は指定した列を直接削除します。
>>> df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
>>> df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> df.drop(columns=['A'])
B C
0 4 7
1 5 8
2 6 9
>>> df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> df.drop(columns=['A', 'C'])
B
0 4
1 5
2 6
>>> df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> df.drop(columns=['A', 'C'], inplace=True)
>>> df
B
0 4
1 5
2 6
>>> df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
>>> df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> del df['B']
>>> df
A C
0 1 7
1 2 8
2 3 9
列名の変更するには、メソッド rename() を使います。
辞書型で指定した列名だけを変更します。なお、df.columns = ['新名1', '新名2', '新名3', ...] で、すべての列名を新しいリストで一括上書きすることができます。
>>> df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> df.rename(columns={'A': 'AA', 'C': 'CC'})
AA B CC
0 1 4 7
1 2 5 8
2 3 6 9
>>> df.columns = ['foo', 'bar', 'baz']
>>> df
foo bar baz
0 1 4 7
1 2 5 8
2 3 6 9
データフレーム全体、またはグループ化されたデータに対して直接呼び出せる代表的な集計関数を以下に示します。
なお、メソッド describe() を使うと、平均、最大値、最小値などの統計量を一括で計算することができます。
簡単な実行例を示しましょう。
リスト : 身長のデータ
df_height = pd.DataFrame({
'Name': ['Ada', 'Alice', 'Carey', 'Ellen', 'Hanna', 'Janet',
'Linda', 'Maria', 'Miranda', 'Sara', 'Tracy', 'Violet'],
'Height': [148.7, 149.5, 133.7, 157.9, 154.2, 147.8,
154.6, 159.1, 148.2, 153.1, 138.2, 138.7],
'Class': ['A', 'B', 'C', 'D', 'A', 'B',
'C', 'D', 'A', 'B', 'C', 'D']
})
>>> df_height
Name Height Class
0 Ada 148.7 A
1 Alice 149.5 B
2 Carey 133.7 C
3 Ellen 157.9 D
4 Hanna 154.2 A
5 Janet 147.8 B
6 Linda 154.6 C
7 Maria 159.1 D
8 Miranda 148.2 A
9 Sara 153.1 B
10 Tracy 138.2 C
11 Violet 138.7 D
>>> df_height.describe()
Height
count 12.000000
mean 148.641667
std 8.057347
min 133.700000
25% 145.525000
50% 149.100000
75% 154.300000
max 159.100000
>>> df_height['Height'].sum()
np.float64(1783.7)
>>> df_height['Height'].mean()
np.float64(148.64166666666668)
>>> df_height['Height'].max()
np.float64(159.1)
>>> df_height['Height'].min()
np.float64(133.7)
>>> df_height['Height'].median()
np.float64(149.1)
>>> df_height['Height'].std()
np.float64(8.057346544200104)
>>> df_height['Height'].var()
np.float64(64.92083333333338)
データフレームでデータを集計する最も一般的で強力な方法は、メソッド groupby() を使用することです。特定の列でデータをグループ分けし、合計や平均などの統計量を計算することができます。
簡単な実行例を示しましょう。Class ごとにデータを集計します。
>>> df_height.groupby('Class')['Height'].mean()
Class
A 150.366667
B 150.133333
C 142.166667
D 151.900000
Name: Height, dtype: float64
>>> df_height.groupby('Class')['Height'].max()
Class
A 154.2
B 153.1
C 154.6
D 159.1
Name: Height, dtype: float64
>>> df_height.groupby('Class')['Height'].min()
Class
A 148.2
B 147.8
C 133.7
D 138.7
Name: Height, dtype: float64
>>> df_height.groupby('Class')['Height'].std()
Class
A 3.329164
B 2.706166
C 11.000152
D 11.447270
Name: Height, dtype: float64
>>> df_height.groupby('Class')['Height'].describe()
count mean std min 25% 50% 75% max
Class
A 3.0 150.366667 3.329164 148.2 148.45 148.7 151.45 154.2
B 3.0 150.133333 2.706166 147.8 148.65 149.5 151.30 153.1
C 3.0 142.166667 11.000152 133.7 135.95 138.2 146.40 154.6
D 3.0 151.900000 11.447270 138.7 148.30 157.9 158.50 159.1
一度に複数の集計を行いたい場合はメソッド agg() を使います。
agg() の引数には関数名 (文字列) を渡します。複数の関数を渡す場合はリスト (またはタプル) に格納して渡します。辞書を渡す場合、キーが関数を適用する列名になります。簡単な例を示しましょう。
>>> df_height.groupby('Class')['Height'].agg('sum')
Class
A 451.1
B 450.4
C 426.5
D 455.7
Name: Height, dtype: float64
>>> df_height.groupby('Class')['Height'].agg(['sum', 'mean'])
sum mean
Class
A 451.1 150.366667
B 450.4 150.133333
C 426.5 142.166667
D 455.7 151.900000
>>> df_height.groupby('Class').agg({'Height': ['min', 'mean', 'max']})
Height
min mean max
Class
A 148.2 150.366667 154.2
B 147.8 150.133333 153.1
C 133.7 142.166667 154.6
D 138.7 151.900000 159.1
>>> df_height.groupby('Class').agg({'Name': 'count', 'Height': ['min', 'mean', 'max']})
Name Height
count min mean max
Class
A 3 148.2 150.366667 154.2
B 3 147.8 150.133333 153.1
C 3 133.7 142.166667 154.6
D 3 138.7 151.900000 159.1
複数の集計を行うと列がマルチインデックス (二重) になりますが、新列名=(元列名, 集計関数) という構文を使うと、フラットな列名で出力することができます。
>>> df_height.groupby('Class').agg(NameCnt=('Name', 'count'), HeightMax=('Height', 'max'),
HeightMin=('Height','min'))
NameCnt HeightMax HeightMin
Class
A 3 154.2 148.2
B 3 153.1 147.8
C 3 154.6 133.7
D 3 159.1 138.7
Pandas の apply() メソッドは、DataFrame や Series の行、列、または各要素に対して、任意の関数を一括で適用する高階関数です。map() は、Series の各要素を別の値に変換します。辞書データを用いた一対一の置換や、関数 (lambda など) を適用した一括処理によく使われます。
1. s.apply(func) => new_series
シリーズ s の要素に関数 func を適用 2. df.apply(func, axis=0) => new_series
データフレーム df の列に関数 func を適用 (デフォルト) 3. df.apply(func, axis=1) => new_series
データフレーム df の行に関数 func を適用
1 は Python の関数 map と同じ動作ですが、シリーズを返すところが異なります。2 は df の列に func を適用し、その結果をシリーズに格納して返します。func の返り値がシリーズの場合、apply() の返り値はデータフレームになります。3 は df の行に func を適用します。簡単な使用例を示しましょう。
>>> s = pd.Series([1, 2, 3, 4, 5])
>>> s
0 1
1 2
2 3
3 4
4 5
dtype: int64
>>> s.apply(lambda x: x * x)
0 1
1 4
2 9
3 16
4 25
dtype: int64
>>> df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
>>> df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
>>> s.product()
np.int64(120)
>>> df.apply(lambda col: col.product())
A 6
B 120
C 504
dtype: int64
>>> df.apply(lambda row: row.product(), axis=1)
0 28
1 80
2 162
dtype: int64
>>> df.apply(lambda row: pd.Series([row['B'] / row['A'], row['C'] / row['A']]), axis=1)
0 1
0 4.0 7.0
1 2.5 4.0
2 2.0 3.0
1. s.map(dic) => new-series 2. s.map(func) => new-series 3. df.map(func) => new-dataframe
s はシリーズで、df はデータフレームとします。1 は辞書 dic (key, value) の key と等しい要素を value に変換します。key が見つからない場合は NaN に変換されます。2 は s.apply() と同じです。3 はデータフレームの要素に関数 func を適用し、その結果を格納した新しいデータフレームを返します。
>>> s
0 1
1 2
2 3
3 4
4 5
dtype: int64
>>> s.map({1: 10, 3: 30, 5: 50})
0 10.0
1 NaN
2 30.0
3 NaN
4 50.0
dtype: float64
>>> s.map(lambda x: x * x)
0 1
1 4
2 9
3 16
4 25
dtype: int64
>>> df.map(lambda x: x * 2)
A B C
0 2 8 14
1 4 10 16
2 6 12 18
Pandas でデータフレームを結合する場合、目的によって merge() と concat() の 2 つの関数を使い分けます。
merge() のオプション on は結合の基準にする列名です。両方のデータフレームに共通の列名が必要ですが、左右で列名が異なる場合は、left_on='左の列名', right_on='右の列名' と指定します。how は結合方法を指定します。
inner 以外の場合、存在しないデータは NaN になります。簡単な例を示しましょう。
リスト : merge() の簡単な例題
df1 = pd.DataFrame({
'id': [1, 2, 3, 4],
'name': ['foo', 'bar', 'baz', 'oops']
})
df2 = pd.DataFrame({
'id': [1, 2, 3, 3, 1, 2, 1],
'color': ['red', 'blue', 'green', 'red', 'blue', 'green', 'pink']
})
df1 は id と name を保持し、df2 では id と color を保持しています。inner (内部結合) を使うと、name と color の関係を簡単に求めることができます。
>>> df1 id name 0 1 foo 1 2 bar 2 3 baz 3 4 oops >>> df2 id color 0 1 red 1 2 blue 2 3 green 3 3 red 4 1 blue 5 2 green 6 1 pink >>> pd.merge(df1, df2, on='id') id name color 0 1 foo red 1 1 foo blue 2 1 foo pink 3 2 bar blue 4 2 bar green 5 3 baz green 6 3 baz red
同じデータが複数ある場合、その数だけテーブル結合が行われます。df1.id と df2.id が等しいデータを取り出して結合するので、foo には 3 つの色 (bule, pink, red)、bar には 2 つの色 (blue, green), baz には 2 つの色 (green, red) があることがわかります。oops の id は 4 ですが、df2 の id に 4 はないので、id = 4 のデータが取り出されることはありません。
outer (外部結合) は on で指定した列の値が一致するデータだけではなく、どちらかのテーブルにデータが存在すれば、それもいっしょに取り出す方法です。
>>> pd.merge(df1, df2, on='id', how='outer') id name color 0 1 foo red 1 1 foo blue 2 1 foo pink 3 2 bar blue 4 2 bar green 5 3 baz green 6 3 baz red 7 4 oops NaN
id が 4 のデータは df1 にはありますが df2 にはありません。そのような場合でも、外部結合すると df1 の id = 4 のデータを取り出すことができます。この場合、color の値は NaN になります。
left は条件を満たさない場合でも、df1 (左側) のデータを取り出します。right は条件を満たさない場合でも右側のデータを取り出します。
>>> pd.merge(df1, df2, on='id', how='left') id name color 0 1 foo red 1 1 foo blue 2 1 foo pink 3 2 bar blue 4 2 bar green 5 3 baz green 6 3 baz red 7 4 oops NaN >>> pd.merge(df1, df2, on='id', how='right') id name color 0 1 foo red 1 2 bar blue 2 3 baz green 3 3 baz red 4 1 foo blue 5 2 bar green 6 1 foo pink
left は左側のデータを残すので、df1 の oops を取り出すことができます。逆に、right は右側のデータを残すので、df1 の oops は捨てられます。
関数 concat() は複数のデータフレームを、リスト形式で指定してそのまま結合します。主なオプションを以下に示します。
簡単な実行例を示します。
>>> df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
>>> df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
>>> df1
A B
0 1 3
1 2 4
>>> df2
A B
0 5 7
1 6 8
>>> pd.concat([df1, df2])
A B
0 1 3
1 2 4
0 5 7
1 6 8
>>> pd.concat([df1, df2], ignore_index=True)
A B
0 1 3
1 2 4
2 5 7
3 6 8
>>> pd.concat([df1, df2], axis = 1)
A B A B
0 1 3 5 7
1 2 4 6 8
>>> df3 = pd.DataFrame({'C': [9, 10], 'D': [11, 12]}, index=[2, 3])
>>> df3
C D
2 9 11
3 10 12
>>> pd.concat([df1, df3])
A B C D
0 1.0 3.0 NaN NaN
1 2.0 4.0 NaN NaN
2 NaN NaN 9.0 11.0
3 NaN NaN 10.0 12.0
>>> pd.concat([df1, df3], join='inner')
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]
>>> pd.concat([df1, df3], axis=1)
A B C D
0 1.0 3.0 NaN NaN
1 2.0 4.0 NaN NaN
2 NaN NaN 9.0 11.0
3 NaN NaN 10.0 12.0
>>> pd.concat([df1, df3], axis=1, join='inner')
Empty DataFrame
Columns: [A, B, C, D]
Index: []
Pandas でデータをソートするには、df.sort_values() か df.sort_index() を使います。
sort_values() は特定の列の値でソートします。第 1 基準、第 2 基準をリストで渡すことで、複数列の組み合わせソートが可能です。sort_index() はインデックス番号 (行名) でソートします。ascending=False を指定すると、降順でソートします。デフォルトは昇順 (ascending=False) です。通常はソート後の新しい DataFrame が返されます。元の DataFrame を書き換えたい場合は inplace=True を指定します。
簡単な実行例を示します。
>>> df_height
Name Height Class
0 Ada 148.7 A
1 Alice 149.5 B
2 Carey 133.7 C
3 Ellen 157.9 D
4 Hanna 154.2 A
5 Janet 147.8 B
6 Linda 154.6 C
7 Maria 159.1 D
8 Miranda 148.2 A
9 Sara 153.1 B
10 Tracy 138.2 C
11 Violet 138.7 D
>>> df_height.sort_values(by='Height')
Name Height Class
2 Carey 133.7 C
10 Tracy 138.2 C
11 Violet 138.7 D
5 Janet 147.8 B
8 Miranda 148.2 A
0 Ada 148.7 A
1 Alice 149.5 B
9 Sara 153.1 B
4 Hanna 154.2 A
6 Linda 154.6 C
3 Ellen 157.9 D
7 Maria 159.1 D
>>> df_height
Name Height Class
0 Ada 148.7 A
1 Alice 149.5 B
2 Carey 133.7 C
3 Ellen 157.9 D
4 Hanna 154.2 A
5 Janet 147.8 B
6 Linda 154.6 C
7 Maria 159.1 D
8 Miranda 148.2 A
9 Sara 153.1 B
10 Tracy 138.2 C
11 Violet 138.7 D
>>> df_height.sort_values(by='Height', ascending=False)
Name Height Class
7 Maria 159.1 D
3 Ellen 157.9 D
6 Linda 154.6 C
4 Hanna 154.2 A
9 Sara 153.1 B
1 Alice 149.5 B
0 Ada 148.7 A
8 Miranda 148.2 A
5 Janet 147.8 B
11 Violet 138.7 D
10 Tracy 138.2 C
2 Carey 133.7 C
>>> df_height.sort_values(by='Class')
Name Height Class
0 Ada 148.7 A
4 Hanna 154.2 A
8 Miranda 148.2 A
1 Alice 149.5 B
5 Janet 147.8 B
9 Sara 153.1 B
2 Carey 133.7 C
6 Linda 154.6 C
10 Tracy 138.2 C
3 Ellen 157.9 D
7 Maria 159.1 D
11 Violet 138.7 D
>>> df_height.sort_values(by=['Class', 'Height'])
Name Height Class
8 Miranda 148.2 A
0 Ada 148.7 A
4 Hanna 154.2 A
5 Janet 147.8 B
1 Alice 149.5 B
9 Sara 153.1 B
2 Carey 133.7 C
10 Tracy 138.2 C
6 Linda 154.6 C
11 Violet 138.7 D
3 Ellen 157.9 D
7 Maria 159.1 D
>>> df_height.sort_values(by='Height', inplace=True)
>>> df_height
Name Height Class
2 Carey 133.7 C
10 Tracy 138.2 C
11 Violet 138.7 D
5 Janet 147.8 B
8 Miranda 148.2 A
0 Ada 148.7 A
1 Alice 149.5 B
9 Sara 153.1 B
4 Hanna 154.2 A
6 Linda 154.6 C
3 Ellen 157.9 D
7 Maria 159.1 D
>>> df_height.sort_index()
Name Height Class
0 Ada 148.7 A
1 Alice 149.5 B
2 Carey 133.7 C
3 Ellen 157.9 D
4 Hanna 154.2 A
5 Janet 147.8 B
6 Linda 154.6 C
7 Maria 159.1 D
8 Miranda 148.2 A
9 Sara 153.1 B
10 Tracy 138.2 C
11 Violet 138.7 D
>>> df_height
Name Height Class
2 Carey 133.7 C
10 Tracy 138.2 C
11 Violet 138.7 D
5 Janet 147.8 B
8 Miranda 148.2 A
0 Ada 148.7 A
1 Alice 149.5 B
9 Sara 153.1 B
4 Hanna 154.2 A
6 Linda 154.6 C
3 Ellen 157.9 D
7 Maria 159.1 D
>>> df_height.sort_index(inplace=True)
>>> df_height
Name Height Class
0 Ada 148.7 A
1 Alice 149.5 B
2 Carey 133.7 C
3 Ellen 157.9 D
4 Hanna 154.2 A
5 Janet 147.8 B
6 Linda 154.6 C
7 Maria 159.1 D
8 Miranda 148.2 A
9 Sara 153.1 B
10 Tracy 138.2 C
11 Violet 138.7 D
Pandas を使ったファイルの入出力は、関数 pd.read_xxxx() とメソッド df.to_xxxx() を使用します。CSV 形式の場合、以下の関数とメソッドになります。
読み込み: df = pd.read_csv("input.csv")
書き出し: df.write_csv("output.csv", index=False)
CSV 形式ファイルとして保存する場合、index=False を指定すると、左端の行番号を出力しません。デフォルトは index=True です。簡単な使用例を示しましょう。
>>> df_height.to_csv('height.csv', index=False)
>>> height = pd.read_csv('height.csv')
>>> height
Name Height Class
0 Ada 148.7 A
1 Alice 149.5 B
2 Carey 133.7 C
3 Ellen 157.9 D
4 Hanna 154.2 A
5 Janet 147.8 B
6 Linda 154.6 C
7 Maria 159.1 D
8 Miranda 148.2 A
9 Sara 153.1 B
10 Tracy 138.2 C
11 Violet 138.7 D
Pandas の基本的な使い方を簡単に説明しました。Pandas は高機能かつ多機能なライブラリなので、初心者が使いこなすのはちょっと大変だと思いますが、基本的な操作はそれほど難しくはありません。興味のある方はいろいろ試してみてください。