Python を使ったデータ分析¶
Python の基礎を学んだので、Python でデータ整理、分析をする際に役立つパッケージを紹介します。
Numpy¶
numpy
は行列計算用のパッケージです。 内部は C で実装されており、高速に計算をすることができます。 また、anaconda を使って python をインストールした場合には、 計算に Intel の Math Kernel Library が使われており、さらに高速に計算をすることができます。 numpy
は np
として 略して import するのが慣習です。
[1]:
import numpy as np
ndarray¶
numpy では ndarray
オブジェクトが行列です。 ndarray
を作るには、array
関数を用いて、次のようにシークエンス型(リストやタプルなど)を渡します。
[2]:
np.array([1, 2, 3])
[2]:
array([1, 2, 3])
リストを 1 つ渡すとベクトル、行列にするにはリストの中にリストを渡します。 各リストが行に相当されます。 リストをさらに入れ子にすると、より多次元にすることができます。
[3]:
np.array([[1, 2, 3], [4, 5, 6]])
[3]:
array([[1, 2, 3],
[4, 5, 6]])
リストの長さを同じにしないと、リストのベクトルが作成されてしまうので注意してください。
[4]:
np.array([[1, 2, 3], [4, 5]])
[4]:
array([list([1, 2, 3]), list([4, 5])], dtype=object)
各要素を参照するのは、リストと同様の方法ですが、行列の場合、参照できるのは行と列です。 [1]
とすると、1 行目が参照されます。[:,1]
とすると、1 列目が参照されます。 [1,1]
とすれば、1 行目の 1 列目の要素が参照されます。
[5]:
A = np.array([[1, 2, 3], [4, 5, 6]])
A
[5]:
array([[1, 2, 3],
[4, 5, 6]])
[6]:
A[1]
[6]:
array([4, 5, 6])
[7]:
A[:, 1]
[7]:
array([2, 5])
[8]:
A[1, 1]
[8]:
5
n x m の ndarray
に対し、同じ行列数で要素が bool 型の ndarray
を渡すと、True
の要素のみが返ってきます。
[9]:
mask = np.array([[True, False, True], [False, False, True]])
A[mask]
[9]:
array([1, 3, 6])
各要素が条件式を満たすかどうかを確認することが可能です。 この結果を用いて、条件を満たす要素のみを参照することも可能です。
[10]:
A > 4
[10]:
array([[False, False, False],
[False, True, True]])
[11]:
A[A > 4]
[11]:
array([5, 6])
複数の条件も設定できます。各条件は ()
で囲み、&
ならば積集合、|
ならば和集合になります。
[12]:
(A > 4) & (A < 8)
[12]:
array([[False, False, False],
[False, True, True]])
[13]:
(A < 3) | (A > 8)
[13]:
array([[ True, True, False],
[False, False, False]])
array
以外にも ndarray
を生成する方法があります。 例えば、arange
は range
関数と同じような挙動で ndarray を生成します。
[14]:
np.arange(1, 10)
[14]:
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
ones
は 1 のみの ndarray、zeros
は 0 のみの ndarray を生成します。
[15]:
np.ones((3, 3))
[15]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
[16]:
np.zeros((3, 3))
[16]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
reshape
を使えば、n x m 行列を l x k 行列に変更できます。
[17]:
C = np.arange(1, 10)
C
[17]:
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
[18]:
np.reshape(C,(3, 3))
[18]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
同名のメソッドもあります。
[19]:
C.reshape((3, 3))
[19]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
属性¶
ndarray
の属性には、例えば、配列の行列数を返す shape
や 要素の型を返す dtype
などがあります。
[20]:
A = np.array([[1, 2, 3], [4, 5, 6]])
A.shape
[20]:
(2, 3)
[21]:
A.dtype
[21]:
dtype('int64')
T
で転置行列を返します。
[22]:
A.T
[22]:
array([[1, 4],
[2, 5],
[3, 6]])
行列計算¶
先述したように、numpy
では様々な行列計算をすることができます。
[23]:
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
B = np.array([[9, 8, 7], [6, 5, 4], [3, 2, 1]])
まずは行列の加算です。
[24]:
A + B
[24]:
array([[10, 10, 10],
[10, 10, 10],
[10, 10, 10]])
dot
または @
で行列の積を計算します。
[25]:
A @ B
[25]:
array([[ 30, 24, 18],
[ 84, 69, 54],
[138, 114, 90]])
[26]:
np.dot(A, B)
[26]:
array([[ 30, 24, 18],
[ 84, 69, 54],
[138, 114, 90]])
*
を使うと、各要素をかけ合わせます。
[27]:
A * B
[27]:
array([[ 9, 16, 21],
[24, 25, 24],
[21, 16, 9]])
linalg
は様々な線形代数の計算をする関数が含まれています。 例えば、inv
は逆行列を計算します。
[28]:
C = np.array([[1, 3, 5], [2, 9, 7], [2, 8, 4]])
np.linalg.inv(C)
[28]:
array([[ 1.66666667, -2.33333333, 2. ],
[-0.5 , 0.5 , -0.25 ],
[ 0.16666667, 0.16666667, -0.25 ]])
ここで実際に、numpy
の計算が高速だという例をお見せします。 10000 個の要素を足し合わせていく作業をループ文と numpy の sum
を使って試してみます。 セルの最初に %%timeit
を使うことによって、そのセルの計算速度を測定できます。
[29]:
%%timeit
sum_Z = 0
for i in range(10000):
sum_Z += 1
1.26 ms ± 174 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
[30]:
Z = np.ones(10000)
[31]:
%%timeit
np.sum(Z)
20.8 µs ± 7.98 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
大規模な計算をするときは、できるだけ numpy
を使うのを勧めます。
ブロードキャスト¶
ndarray
には、ブロードキャストという機能がついています。 これによって、配列の行列数が違う場合にも計算を可能にします。 実際に見てみましょう。行列の加算は配列の数が同じもの同士に定義されますが、X と Y は配列数が違います。 この 2 つを足してみます。
[32]:
X = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
Y = np.array([[1, 2, 3]])
X + Y
[32]:
array([[ 2, 4, 6],
[ 5, 7, 9],
[ 8, 10, 12]])
この結果は次の計算によるものであることは明らかですね。
[33]:
Y_wide = np.array([[1, 2, 3],[1 ,2, 3],[1, 2, 3]])
X + Y_wide
[33]:
array([[ 2, 4, 6],
[ 5, 7, 9],
[ 8, 10, 12]])
ブロードキャストというのは、つまり、行列同士を計算できるように、配列数が足りない行列を引き伸ばしてくれるということです。 例えば、ある数字を全ての要素に足したい場合、行列数を同じにしないでもすむというメリットがあります。
乱数生成¶
Python にも random
という疑似乱数を生成するモジュールがありますが、numpy の random
はより高機能です。 計量経済学をするなら気になるところですね。 さっそく見ていきましょう。 rand
は一様分布から疑似乱数を生成します。引数に配列数を渡します。
[34]:
np.random.rand(3, 3)
[34]:
array([[0.81604635, 0.9374695 , 0.61670905],
[0.15385651, 0.35901032, 0.84625432],
[0.88591126, 0.40596778, 0.14039651]])
randn
は標準正規分布からの疑似乱数を発生させます。
[35]:
np.random.randn(3, 3)
[35]:
array([[ 1.28406631, -0.53822411, 0.80013257],
[ 0.81690022, -0.58300972, -2.70036416],
[-0.59812875, -1.26783858, 0.7256989 ]])
choice
は引数に渡した 1 次元の ndarray もしくはリストからランダムに要素を抽出します。
[36]:
countries = ['Japan', 'China', 'Korea']
np.random.choice(countries)
[36]:
'Japan'
引数には要素を抽出する回数、復元抽出か非復元抽出か、各要素を抽出する確率を渡せます。
[37]:
np.random.choice(countries, size = 2)
[37]:
array(['Japan', 'China'], dtype='<U5')
[38]:
np.random.choice(countries, size = 2, replace = False)
[38]:
array(['China', 'Korea'], dtype='<U5')
[39]:
np.random.choice(countries, size = 2, p = [0.9, 0.05, 0.05])
[39]:
array(['Japan', 'Japan'], dtype='<U5')
一様分布や標準正規分布といったおなじみのもの以外にも、ベータ関数やラプラス分布、ロジスティック分布などから疑似乱数を生成することもできます。 次の例は、自由度 5 の\(\chi^2\)分布から疑似乱数を生成しています。
[40]:
np.random.chisquare(5, 3)
[40]:
array([4.15855897, 6.61777927, 5.16556098])
Scipy¶
scipy
を語るにはスペースが足りないほど、scipy
は統計、機械学習、画像処理など様々な科学計算用の関数を備えています。 ネーミングセンスからお分かりのように、scipy
は numpy
と併用して用います。 せっかくなので、いくつか見ていきましょう。
optimize¶
scipy
はそ機能の大きさのため、各機能毎に import することが勧められています。 optimize
は最適化に関する関数を備えています。 brentq
は方程式の解を見つけ出します。
[41]:
from scipy import optimize as opt
def func1(x):
fx = 3 * x - 5
return fx
opt.brentq(func1, -10, 10)
[41]:
1.666666666666666
minimize
は関数の最小値を探す関数です。オプションによって、様々な探索アルゴリズムを選択できます。
[42]:
def func2(x):
fx = x ** 2 + 3 * x - 5
return fx
opt.minimize(func2, 0)
[42]:
fun: -7.25
hess_inv: array([[0.5]])
jac: array([0.])
message: 'Optimization terminated successfully.'
nfev: 9
nit: 2
njev: 3
status: 0
success: True
x: array([-1.50000001])
stats¶
stats
は統計分析に関する関数を備えています。 例えば、numpy
のように疑似乱数を生成することも可能です。 norms.rvs
とすると、正規分布の疑似乱数を生成します。
[43]:
from scipy import stats
stats.norm.rvs(loc = 0, scale = 1, size = 10)
[43]:
array([ 1.00585753, -1.03111348, 0.16008137, -0.2425014 , 0.02450575,
0.88017105, -1.32771746, -0.59314082, -0.15458929, -1.02338975])
rvs
は疑似乱数の生成ですが、他にも豊富なメソッドがあります。 例えば、
pdf
: 確率密度関数の値を返すcdf
: 累積密度関数の値を返すppf
: パーセント点の値を返す
[44]:
stats.norm.pdf(x = 0, loc = 0, scale = 1)
[44]:
0.3989422804014327
[45]:
stats.norm.cdf(x = 0, loc = 0, scale = 1)
[45]:
0.5
[46]:
stats.norm.ppf(q = 0.05, loc = 0, scale = 1)
[46]:
-1.6448536269514729
検定もすることも可能です。
例えば、ttest_ind
は 2 つのデータ (ndarray
) の差を t 検定します。
[47]:
N_A = stats.norm.rvs(loc = -5, scale = 1, size = 10)
N_B = stats.norm.rvs(loc = 3, scale = 1, size = 10)
stats.ttest_ind(N_A,N_B)
[47]:
Ttest_indResult(statistic=-20.51082893599917, pvalue=6.229373675859823e-14)
Pandas¶
pandas
は 様々な I/O (入出力) 処理、高機能なデータ処理をすることができるパッケージです。 pandas
のデータ型は、Series
と DataFrame
です。 Series
はラベル付きのベクトル、DataFrame
はラベル付きの行列です。 R を使ったことがある人はピンとくるかもしれませんが、DataFrame
は R の data.frame 型と同じようなものです。 実際、pandas は R のデータ整理用のパッケージ、dplyr
でできることの多くを実装しています。 pandas
は pd
と略して import するのが慣習です。
それでは、Series
から見ていきましょう。
[48]:
import pandas as pd
Series¶
Series の作り方は、numpy の1次元の ndarray
と同じようなものです。
[49]:
pd.Series([1, 2, 3])
[49]:
0 1
1 2
2 3
dtype: int64
ndarray
とは似ていますが、異なるところもあります。 まず、左側に index が表示されていますね。 この index は好きなようにラベルを付けることも可能です。
[50]:
pd.Series([1, 2, 3], index = ['one', 'two', 'three'])
[50]:
one 1
two 2
three 3
dtype: int64
Series に名前を付けることも可能です。
[51]:
pd.Series([1, 2, 3], index = ['one', 'two', 'three'], name = 'numbers')
[51]:
one 1
two 2
three 3
Name: numbers, dtype: int64
index、要素、名前などが属性として参照できます。
[52]:
A_s = pd.Series([1, 2, 3], index = ['one', 'two', 'three'], name = 'numbers')
[53]:
A_s.index
[53]:
Index(['one', 'two', 'three'], dtype='object')
[54]:
A_s.values
[54]:
array([1, 2, 3])
[55]:
A_s.name
[55]:
'numbers'
要素を参照すると、ndarray
が返ってきました。 pandas
と numpy
との間は簡単に行き来することができます。 今度は ndarray
を Series
にしてみます。
[56]:
A_np = np.array([1, 2, 3])
A_index = np.array(['one', 'two', 'three'])
pd.Series(A_np, index = A_index)
[56]:
one 1
two 2
three 3
dtype: int64
後で見ますが、DataFrame
でも同じことができます。 実際にデータ分析をする際には、まず pandas
を使ってデータを整理し、numpy
や scipy
を使って分析を行うという流れになると思います。
要素の参照¶
Series
は様々な方法で要素を参照することができます。 まず、要素の番号を入れて参照してみましょう。
[57]:
A_s
[57]:
one 1
two 2
three 3
Name: numbers, dtype: int64
[58]:
A_s[1]
[58]:
2
index 名で要素を参照することも可能です。
[59]:
A_s['three']
[59]:
3
参照した要素に違う値を代入してみます。
[60]:
A_s['three'] = 5
A_s
[60]:
one 1
two 2
three 5
Name: numbers, dtype: int64
numpy
のところで説明したように、各要素が条件式を満たしているかを判別できます。 また、この結果を用いて条件式を満たす要素を参照できます。
[61]:
A_s > 2
[61]:
one False
two False
three True
Name: numbers, dtype: bool
[62]:
A_s[A_s > 2]
[62]:
three 5
Name: numbers, dtype: int64
計算¶
Series
の計算は numpy
の時と違います。 Series
では四則演算は index が同じもの同士で行います。
[63]:
A_s = pd.Series([1, 2, 3], index = ['one', 'two', 'three'])
B_s = pd.Series([4, 5, 6], index = ['one', 'two', 'three'])
B_s
[63]:
one 4
two 5
three 6
dtype: int64
[64]:
A_s + B_s
[64]:
one 5
two 7
three 9
dtype: int64
[65]:
A_s - B_s
[65]:
one -3
two -3
three -3
dtype: int64
[66]:
A_s * B_s
[66]:
one 4
two 10
three 18
dtype: int64
[67]:
A_s / B_s
[67]:
one 0.25
two 0.40
three 0.50
dtype: float64
index が同じもの同士で計算するので、商も定義されます。 index が合致しないものは NaN (Not a number) が返ってきます。
[68]:
C_s = pd.Series([1, 2, 3], index = ['one', 'two', 'four'])
C_s
[68]:
one 1
two 2
four 3
dtype: int64
[69]:
A_s + C_s
[69]:
four NaN
one 2.0
three NaN
two 4.0
dtype: float64
文字列操作¶
Series には str
という強力な文字列操作のメソッドが備わっています。 これを用いることによって、データのクリーニングが非常に楽になります。 まずは、基本的な操作からしていきましょう。 lower
は文字列を小文字に、upper
は文字列を大文字に、len
は文字列の文字数をカウントします。
[70]:
small_text = pd.Series(['A', 'B', 'C'])
small_text.str.lower()
[70]:
0 a
1 b
2 c
dtype: object
[71]:
large_text = pd.Series(['a', 'b', 'c'])
large_text.str.upper()
[71]:
0 A
1 B
2 C
dtype: object
[72]:
number_text = pd.Series(['one', 'two', 'three'])
number_text.str.len()
[72]:
0 3
1 3
2 5
dtype: int64
extract
は指定した文字を抜き出します。
[73]:
number_with_text = pd.Series(['one1', 'two2', 'three3'])
number_with_text.str.extract(r'(\d)', expand = False)
[73]:
0 1
1 2
2 3
dtype: object
\d
は 正規表現 というもので、パターンマッチングをする際に強力な助けとなります。 正規表現はマッチングしたい文字列の条件式を非常に簡単に書くことができます。 いくつかの文字はメタキャラクタというもので、例えば \d
は任意の数とマッチングするという意味です。 さきほどの文は、文頭から文字を参照していき、任意の数が当たったらその文字を抜き出す ということをしています。 マッチングの文に正規表現を使う場合は最初に r
を付けておきましょう。
先程とは逆に、任意の数字以外の文字列を抜き出す場合次のようにします。 \D
は数以外の任意の文字とマッチングします。 +
は直前のマッチング式が一致していたら、それを繰り返します。 例えば、two+
は two
も twoooooooo
とも一致しますが、tw
とは一致しません。
[74]:
number_with_text.str.extract(r'(\D+)', expand = False)
[74]:
0 one
1 two
2 three
dtype: object
replace
はマッチした文字列を指定した文字列に置き換えます。
[75]:
number_with_text.str.replace(r'(\d)', '')
[75]:
0 one
1 two
2 three
dtype: object
match
はマッチング文が先頭からマッチしているか、contains
はマッチング文を含んでいるかを返します。
[76]:
match_text = pd.Series(['1', 'one2', 'one'])
match_text
[76]:
0 1
1 one2
2 one
dtype: object
[77]:
match_text.str.match(r'\d')
[77]:
0 True
1 False
2 False
dtype: bool
[78]:
match_text.str.contains(r'\d')
[78]:
0 True
1 True
2 False
dtype: bool
get_dummies
はダミー変数を作成できます。 DataFrame
を返します。
[79]:
dummies_text = pd.Series(['one', 'one', 'two'])
dummies_text.str.get_dummies()
[79]:
one | two | |
---|---|---|
0 | 1 | 0 |
1 | 1 | 0 |
2 | 0 | 1 |
sep
で文字列を分けられます。
[80]:
dummies_text = pd.Series(['one|two', 'one', 'two'])
dummies_text.str.get_dummies(sep = '|')
[80]:
one | two | |
---|---|---|
0 | 1 | 1 |
1 | 1 | 0 |
2 | 0 | 1 |
DataFrame¶
DataFrame
は 多次元の ndarray
を作るときと似ています。
[81]:
pd.DataFrame([[1, 2, 3], [4, 5, 6]])
[81]:
0 | 1 | 2 | |
---|---|---|---|
0 | 1 | 2 | 3 |
1 | 4 | 5 | 6 |
Series
と同じように左に index がありますが、さらに上に columns があります。 これらはどちらもラベル付けすることができます。
[82]:
index_list = ['one', 'two']
columns_list = ['a', 'b', 'c']
pd.DataFrame(
[[1, 2, 3], [4, 5, 6]],
index = index_list,
columns = columns_list)
[82]:
a | b | c | |
---|---|---|---|
one | 1 | 2 | 3 |
two | 4 | 5 | 6 |
Series
のように index、columns、要素が属性として用意されています。
[83]:
A_dt = pd.DataFrame(
[[1, 2, 3], [4, 5, 6]],
index = index_list,
columns = columns_list)
[84]:
A_dt.index
[84]:
Index(['one', 'two'], dtype='object')
[85]:
A_dt.columns
[85]:
Index(['a', 'b', 'c'], dtype='object')
[86]:
A_dt.values
[86]:
array([[1, 2, 3],
[4, 5, 6]])
Series
と同じように、要素を参照すると ndarray
が返ってきます。 また、Series
と同じように ndarray
を DataFrame
にすることもできます。
要素の参照¶
DataFrame
にも様々な要素の参照の方法があります。
[87]:
A_dt
[87]:
a | b | c | |
---|---|---|---|
one | 1 | 2 | 3 |
two | 4 | 5 | 6 |
columns の参照は []
か、.columns名
で行います。
[88]:
A_dt['a']
[88]:
one 1
two 4
Name: a, dtype: int64
[89]:
A_dt.b
[89]:
one 2
two 5
Name: b, dtype: int64
複数の columns の参照はリストを使います。
[90]:
A_dt[['a', 'c']]
[90]:
a | c | |
---|---|---|
one | 1 | 3 |
two | 4 | 6 |
index の参照は loc
を使います。 loc[index名, columns名]
とします。
[91]:
A_dt.loc['one']
[91]:
a 1
b 2
c 3
Name: one, dtype: int64
[92]:
A_dt.loc[:, 'c']
[92]:
one 3
two 6
Name: c, dtype: int64
[93]:
A_dt.loc['one', 'b']
[93]:
2
iloc
はラベル名ではなく要素の番号によって参照します。
[94]:
A_dt.iloc[1]
[94]:
a 4
b 5
c 6
Name: two, dtype: int64
[95]:
A_dt.iloc[:, 2]
[95]:
one 3
two 6
Name: c, dtype: int64
[96]:
A_dt.iloc[1, 1]
[96]:
5
要素を参照して値を再代入することもできます。
[97]:
A_dt.loc['one', 'b'] = 5
A_dt
[97]:
a | b | c | |
---|---|---|---|
one | 1 | 5 | 3 |
two | 4 | 5 | 6 |
条件式を満たしているかを判別することもでき、条件式を満足する行を参照することもできます。
[98]:
A_dt > 2
[98]:
a | b | c | |
---|---|---|---|
one | False | True | True |
two | True | True | True |
[99]:
A_dt[A_dt > 2]
[99]:
a | b | c | |
---|---|---|---|
one | NaN | 5 | 3 |
two | 4.0 | 5 | 6 |
ある columns が条件式を満たしている 行を参照することもできます。
[100]:
A_dt.a > 2
[100]:
one False
two True
Name: a, dtype: bool
[101]:
A_dt[A_dt.a > 2]
[101]:
a | b | c | |
---|---|---|---|
two | 4 | 5 | 6 |
反対に、ある index が条件式を満たしている columns を参照することもできます。
[102]:
A_dt.loc['one'] > 2
[102]:
a False
b True
c True
Name: one, dtype: bool
[103]:
A_dt.loc[:, A_dt.loc['one'] > 2]
[103]:
b | c | |
---|---|---|
one | 5 | 3 |
two | 5 | 6 |
I/O (入出力)処理¶
pandas
は多様な I/O 処理をすることができ、 csv ファイル、エクセルファイル、Stata ファイル、R ファイルなどの様々なファイルを入出力することが可能です。 例えば、次の例はエクセルのファイルを読み込んでいます。
[104]:
pd.read_excel('data/excel_example.xlsx')
[104]:
one | two | three | |
---|---|---|---|
0 | 1 | 4 | 7 |
1 | 2 | 5 | 8 |
2 | 3 | 6 | 9 |
次の例は DataFrame
を Stata ファイルに出力しています。
[105]:
A_dt.to_stata('data/stata_output.dta')
グループ化¶
pandas
の DataFrame
には様々なデータ集計の関数が用意されています。 例えば、groupby
は指定した columns の値でグループを作ります。
[106]:
B_dt = pd.DataFrame(
[['one', 1], ['one', 2], ['two', 3], ['two', 4]],
columns = ['num', 'val'])
B_dt
[106]:
num | val | |
---|---|---|
0 | one | 1 |
1 | one | 2 |
2 | two | 3 |
3 | two | 4 |
[107]:
group_dt = B_dt.groupby('num')
group_dt
[107]:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x1a1943cac8>
グループ化した DataFrame
, DataFrameGroupBy
に集計関数を与えることで集計値を獲得できます。 例えば、mean
メソッドは平均値、 std
メソッドは標準偏差が返されます。
[108]:
group_dt.mean()
[108]:
val | |
---|---|
num | |
one | 1.5 |
two | 3.5 |
[109]:
group_dt.std()
[109]:
val | |
---|---|
num | |
one | 0.707107 |
two | 0.707107 |
データの結合¶
pandas
には便利なデータの結合の関数が用意されています。 concat
は単純に DataFrame
同士を結合します。
[110]:
A_dt
[110]:
a | b | c | |
---|---|---|---|
one | 1 | 5 | 3 |
two | 4 | 5 | 6 |
[111]:
index_list = ['one', 'two']
columns_list = ['a', 'b', 'c']
C_dt = pd.DataFrame(
[[4, 5, 6], [7, 8, 9]],
index = index_list,
columns = columns_list)
C_dt
[111]:
a | b | c | |
---|---|---|---|
one | 4 | 5 | 6 |
two | 7 | 8 | 9 |
[112]:
pd.concat([A_dt, C_dt])
[112]:
a | b | c | |
---|---|---|---|
one | 1 | 5 | 3 |
two | 4 | 5 | 6 |
one | 4 | 5 | 6 |
two | 7 | 8 | 9 |
axis = 1
にすることで、横方向の結合をすることができます。
[113]:
pd.concat([A_dt, C_dt], axis = 1)
[113]:
a | b | c | a | b | c | |
---|---|---|---|---|---|---|
one | 1 | 5 | 3 | 4 | 5 | 6 |
two | 4 | 5 | 6 | 7 | 8 | 9 |
append
も同様です。
[114]:
A_dt.append(C_dt)
[114]:
a | b | c | |
---|---|---|---|
one | 1 | 5 | 3 |
two | 4 | 5 | 6 |
one | 4 | 5 | 6 |
two | 7 | 8 | 9 |
merge
はキーを指定して、キーが同じもの同士で index を結合します。
[115]:
B_dt
[115]:
num | val | |
---|---|---|
0 | one | 1 |
1 | one | 2 |
2 | two | 3 |
3 | two | 4 |
[116]:
D_dt = pd.DataFrame(
[['one', 1], ['two', 2], ['three', 3], ['four', 4]],
columns = ['num', 'val'])
D_dt
[116]:
num | val | |
---|---|---|
0 | one | 1 |
1 | two | 2 |
2 | three | 3 |
3 | four | 4 |
[117]:
pd.merge(B_dt, D_dt, on = ['num'])
[117]:
num | val_x | val_y | |
---|---|---|---|
0 | one | 1 | 1 |
1 | one | 2 | 1 |
2 | two | 3 | 2 |
3 | two | 4 | 2 |