はじめに
機械学習の勉強を始めたVBAユーザです。
備忘録としてPython・Rの文法をVBAと比較しながらまとめていきたいと思います。
今回は、データフレームについて、RDBのSQLと比較しながらまとめます。
長くなってしまいましたので、Rのdplyr
パッケージについては別記事にします。
目次
データフレーム
今回は、データフレームについて、RDBのSQLと比較しながらまとめます。
データフレームは、このような形をしたデータで、縦方向に同じデータ型のデータが同じ数だけ並んでいるものです。つまり、列ベクトルを横に並べたようなものです。(ベクトルについてはこちら参照。)
||X|Y|Z|
|--:|:-:|:-:|:-:|:-:|
|1|20|100.1|AAA|
|2|40|200.2|BBB|
|3|10|300.3|CCC|
|4|30|400.4|DDD|
|5|50|500.5|EEE|
縦方向を「行」、横方向を「列」といいます。
Python(pandas) | R | RDB(Access) | Excel | 行列 | |
---|---|---|---|---|---|
オブジェクト | DataFrame | data.frame | テーブル | テーブル | 行列(matrix) |
行 | index(axis=0) | 行(row) | レコード | 行(ROW) | 行(row) |
列 | columns(axis=1) | 列(col) | フィールド | 列(COLUMN) | 列(column) |
要素 | values | 値 | CELL | 要素 |
データフレームの作成
Python
Pythonでは、データ処理ライブラリのpandasのDataFrame型を使います。
pandasは通常 pd
としてインポートしますので、ここでもimport pandas as pd
としてあります(Numpyも使いますのでインポートしています。)。
import numpy as np
import pandas as pd
x = np.array([2,4,1,3,5])*10
y = np.arange(1,5+1)*100+np.arange(1,5+1)/10
z = ['AAA','BBB','CCC','DDD','EEE']
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df = pd.DataFrame(
{
'X': np.array([2,4,1,3,5])*10,
'Y': np.arange(1,5+1)*100+np.arange(1,5+1)/10,
'Z': ['AAA','BBB','CCC','DDD','EEE']
}
)
df
print(df)
# X Y Z
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
# 3 30 400.4 DDD
# 4 50 500.5 EEE
df.dtypes
# X int32
# Y float64
# Z object
# dtype: object
df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 5 entries, 0 to 4
# Data columns (total 3 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 X 5 non-null int32
# 1 Y 5 non-null float64
# 2 Z 5 non-null object
# dtypes: float64(1), int32(1), object(1)
# memory usage: 228.0+ bytes
df['X']
print(df['X'])
# 0 20
# 1 40
# 2 10
# 3 30
# 4 50
# Name: X, dtype: int32
type(df['X'])
# pandas.core.series.Series
pandasのDataFrameの各列は、pandasのSeries型(名前付きの1次元のNumpyのndarrayのようなもの)になっています。
R
Rのデータフレームは、ベクトルを縦ベクトルとして横に並べたリストです。ベクトルから定義できます。
x = c(2,4,1,3,5)*10
y = 1:5*100+1:5/10
z = c("AAA","BBB","CCC","DDD","EEE")
df <- data.frame(X = x, Y = y, Z = z)
df <- data.frame(X = c(2,4,1,3,5)*10,
Y = 1:5*100+1:5/10,
Z = c("AAA","BBB","CCC","DDD","EEE"))
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
class(df)
# [1] "data.frame"
str(df)
# 'data.frame': 5 obs. of 3 variables:
# $ X: num 20 40 10 30 50
# $ Y: num 100 200 300 400 500
# $ Z: Factor w/ 5 levels "AAA","BBB","CCC",..: 1 2 3 4 5
df$X
# [1] 20 40 10 30 50
df$Y
# [1] 100.1 200.2 300.3 400.4 500.5
df$Z
# [1] AAA BBB CCC DDD EEE
# Levels: AAA BBB CCC DDD EEE
class(df$X)
# [1] "numeric"
class(df$Y)
# [1] "numeric"
class(df$Z)
# [1] "factor"
str()
はオブジェクトの構造(structure)を表示する関数です。
data.frame()
では、文字列ベクトルは因子型(Factor)として登録されています(Zが因子型になっています。)。
データフレームの属性
属性の取得
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
df.columns
# Index(['X', 'Y', 'Z'], dtype='object')
df.columns.values
# array(['X', 'Y', 'Z'], dtype=object)
df.index
# RangeIndex(start=0, stop=5, step=1)
df.index.values
# array([0, 1, 2, 3, 4], dtype=int64)
df.values
# array([[20, 100.1, 'AAA'],
# [40, 200.2, 'BBB'],
# [10, 300.3, 'CCC'],
# [30, 400.4, 'DDD'],
# [50, 500.5, 'EEE']], dtype=object)
type(df.values)
# numpy.ndarray
len(df.columns) # 列数
# 3
len(df.columns) # 列数
# 3
len(df.index) # 行数
# 5
len(df) # 行数
# 5
df.shape # (行数, 列数)
# (5, 3)
df.size # 全要素数=行数×列数
15
R
df <- data.frame(X=x, Y=y, Z=z)
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
length(df) # 列数
# [1] 3
ncol(df) # 列数
# [1] 3
nrow(df) # 行数
# [1] 5
names(df) # 列名
# [1] "X" "Y" "Z"
colnames(df) # 列名
# [1] "X" "Y" "Z"
rownames(df) # 行名
# [1] "1" "2" "3" "4" "5"
row.names(df) # 行名
# [1] "1" "2" "3" "4" "5"
dim(df) # 形(行数, 列数)
# [1] 5 3
属性の変更
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
# 列名変更
df.columns = list('xyz') # ['x','y','z']
df
print(df)
# x y z
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
# 3 30 400.4 DDD
# 4 50 500.5 EEE
# 行名変更
df.index = list('abcde')
df
print(df)
# x y z
# a 20 100.1 AAA
# b 40 200.2 BBB
# c 10 300.3 CCC
# d 30 400.4 DDD
# e 50 500.5 EEE
R
df <- data.frame(X=x, Y=y, Z=z)
# 列名変更
names(df) <- c("x","y","z")
df
# x y z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
# 行名変更
row.names(df) <- letters[1:5] # "a" "b" "c" "d" "e"
rownames(df) <- letters[1:5]
df
# x y z
# a 20 100.1 AAA
# b 40 200.2 BBB
# c 10 300.3 CCC
# d 30 400.4 DDD
# e 50 500.5 EEE
データフレームへのアクセス
指定した列へのアクセス
データフレームから列を取り出します。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
df.X
df['X']
print(df['X'])
# 0 20
# 1 40
# 2 10
# 3 30
# 4 50
# Name: X, dtype: int32
type(df['X'])
# pandas.core.series.Series
df[['X']]
print(df[['X']])
df.loc[:,['X']]
print(df.loc[:,['X']])
# X
# 0 20
# 1 40
# 2 10
# 3 30
# 4 50
type(df[['X']])
# pandas.core.frame.DataFrame
df[['X','Z']]
print(df[['X','Z']])
df.loc[:, ['X','Z']]
print(df.loc[:, ['X','Z']])
df.iloc[:, [1-1,3-1]]
print(df.iloc[:, [1-1,3-1]])
# X Z
# 0 20 AAA
# 1 40 BBB
# 2 10 CCC
# 3 30 DDD
# 4 50 EEE
df[['Z','Y','X']]
print(df[['Z','Y','X']])
df.loc[:,['Z','Y','X']]
print(df.loc[:,['Z','Y','X']])
df.iloc[:,[3-1,2-1,1-1]]
print(df.iloc[:,[3-1,2-1,1-1]])
var = ['Z','Y','X']
df.loc[:,var]
print(df.loc[:,var])
# Z Y X
# 0 AAA 100.1 20
# 1 BBB 200.2 40
# 2 CCC 300.3 10
# 3 DDD 400.4 30
# 4 EEE 500.5 50
pandasのDataFrameはSeries(1次元)を横に並べたものです。(●Series型からDataFrameを作れるかは未確認。●)
df.X
,df['X']
は、そのDataFrameのもとになっているSeriesを返します。
df[['X']]
は、df[['X','Z']]
やdf[['Z','Y','X']]
と同じく、DataFrameから指定した列だけ抜き出したもの(その列数がたまたま1個だっただけ)で、DataFrameのsubset(一部)のDataFrameが返ります。
(下の R の場合の注書きも参照。)
R
df <- data.frame(X=x, Y=y, Z=z)
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
df$X
df[["X"]]
df[[1]]
# [1] 20 40 10 30 50
class(df$X)
# [1] "numeric"
df["X"]
df[1]
# X
# 1 20
# 2 40
# 3 10
# 4 30
# 5 50
class(df["X"])
# [1] "data.frame"
df[c(1,3)]
df[c("X","Z")]
# X Z
# 1 20 AAA
# 2 40 BBB
# 3 10 CCC
# 4 30 DDD
# 5 50 EEE
df[c(3,1,2)]
df[c("Z","X","Y")]
var <- c("Z","X","Y")
df[var]
# Z X Y
# 1 AAA 20 100.1
# 2 BBB 40 200.2
# 3 CCC 10 300.3
# 4 DDD 30 400.4
# 5 EEE 50 500.5
df$X
,df[["X"]]
,df[[1]]
とdf["X"]
,df[1]
の違いは、データフレームがベクトルを要素として持つ名前付きリストであったことを考えると理解できます。(これについてはこちら参照。)
df$X
,df[["X"]]
,df[[1]]
はデータフレーム(=名前付きリスト)から"X"という名前の要素(=ベクトル)、1番目の要素(=ベクトル)を取り出していますので、ベクトルが返ります。
df["X"]
,df[1]
は、リストから1つの要素("X"という名前の要素、1番目の要素)だけからなるリストを取る操作ですので、リスト(データフレーム)が返ります。
df[c(3,1,2)]
,df[c("Z","X","Y")]
も同じで、リストから3つの要素からなるリストを取る操作ですので、3つの縦ベクトルからなるリスト(データフレーム)が返ります。
指定した行へのアクセス
先頭の方の行と末尾の方の行を取り出します。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df.head(3)
print(df.head(3))
# X Y Z
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
df.tail(2)
print(df.tail(2))
# X Y Z
# 3 30 400.4 DDD
# 4 50 500.5 EEE
R
df <- data.frame(X=x, Y=y, Z=z)
head(df, 3)
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
tail(df, 2)
# X Y Z
# 4 30 400.4 DDD
# 5 50 500.5 EEE
指定した行と列の選択
データフレームから行・列を指定して取り出します。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df.iat[1-1,1-1]
df.at[1-1,'X']
df.iloc[1-1,1-1]
df.loc[1-1,'X']
df['X'][1-1]
df.X[1-1]
# 20
df.iloc[[1-1,3-1],[1-1,3-1]]
print(df.iloc[[1-1,3-1],[1-1,3-1]])
df.loc[[1-1,3-1],['X','Z']]
print(df.loc[[1-1,3-1],['X','Z']])
# X Z
# 0 20 AAA
# 2 10 CCC
df.iloc[:,[1-1,3-1]]
print(df.iloc[:,[1-1,3-1]])
df.loc[:,['X','Z']]
print(df.loc[:,['X','Z']])
df[['X','Z']]
print(df[['X','Z']])
# X Z
# 0 20 AAA
# 1 40 BBB
# 2 10 CCC
# 3 30 DDD
# 4 50 EEE
df.iloc[[1-1,3-1],:]
# print(df.iloc[[1-1,3-1],:])
df.loc[[1-1,3-1],:]
# print(df.loc[[1-1,3-1],:])
df.iloc[[1-1,3-1]]
# print(df.iloc[[1-1,3-1]])
df.loc[[1-1,3-1]]
# print(df.loc[[1-1,3-1]])
# X Y Z
# 0 20 100.1 AAA
# 2 10 300.3 CCC
loc
もiloc
も選択する場所(location)を指定。loc
とiloc
の違いは、loc
が label-based(名前で指定)、iloc
が integer-location based(番号で指定)。
R
df <- data.frame(X=x, Y=y, Z=z)
df[1,1]
df[1,"X"]
df[[1,1]]
df[[1,"X"]]
df$X[1]
df[["X"]][1]
# [1] 20
df[c(1,3),c(1,3)]
df[c(1,3),c("X","Z")]
df[c(T,F,T,F,F),c(T,F,T)]
# X Z
# 1 20 AAA
# 3 10 CCC
df[,c(1,3)]
df[,c("X","Z")]
df[,c(T,F,T)]
# X Z
# 1 20 AAA
# 2 40 BBB
# 3 10 CCC
# 4 30 DDD
# 5 50 EEE
df[c(1,3),]
df[c(T,F,T,F,F),]
# X Y Z
# 1 20 100.1 AAA
# 3 10 300.3 CCC
1重の角括弧[``]
で指定するとデータフレームが返ります。
データフレームの操作
ここからは、SQLの操作と比較して説明します。
列の選択
SQLのSELECT文に相当する列選択です。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
df[['X']]
print(df[['X']])
df.iloc[:,[1-1]]
print(df.iloc[:,[1-1]])
df.loc[:,['X']]
print(df.loc[:,['X']])
# X
# 0 20
# 1 40
# 2 10
# 3 30
# 4 50
df[['X','Z']]
print(df[['X','Z']])
df.loc[:,['X','Z']]
print(df.loc[:,['X','Z']])
df.iloc[:,[1-1,3-1]]
print(df.iloc[:,[1-1,3-1]])
# X Z
# 0 20 AAA
# 1 40 BBB
# 2 10 CCC
# 3 30 DDD
# 4 50 EEE
df[['Z','Y','X']]
print(df[['Z','Y','X']])
df.loc[:,['Z','Y','X']]
print(df.loc[:,['Z','Y','X']])
df.iloc[:,[3-1,2-1,1-1]]
print(df.iloc[:,[3-1,2-1,1-1]])
var = ['Z','Y','X']
df.loc[:,var]
print(df.loc[:,var])
# Z Y X
# 0 AAA 100.1 20
# 1 BBB 200.2 40
# 2 CCC 300.3 10
# 3 DDD 400.4 30
# 4 EEE 500.5 50
R
df <- data.frame(X=x, Y=y, Z=z)
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
df["X"]
df[1]
# X
# 1 20
# 2 40
# 3 10
# 4 30
# 5 50
df[c(1,3)]
df[c("X","Z")]
df[,c(1,3)]
df[,c("X","Z")]
df[,c(T,F,T)]
# X Z
# 1 20 AAA
# 2 40 BBB
# 3 10 CCC
# 4 30 DDD
# 5 50 EEE
df[c(3,1,2)]
df[c("Z","X","Y")]
var <- c("Z","X","Y")
df[var]
# Z X Y
# 1 AAA 20 100.1
# 2 BBB 40 200.2
# 3 CCC 10 300.3
# 4 DDD 30 400.4
# 5 EEE 50 500.5
SQL
SELECT X FROM df;
SELECT Z, X FROM df;
SELECT Z, X, Y FROM df;
列の追加
データフレームに新しい列を追加する方法についてです。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df['A'] = np.arange(1,5+1,1)
df
df['X3'] = df['X'] * 3
df
df['S'] = list('MFMFM') # ['M', 'F', 'M', 'F', 'M']
df
print(df)
# X Y Z A X3 S
# 0 20 100.1 AAA 1 60 M
# 1 40 200.2 BBB 2 120 F
# 2 10 300.3 CCC 3 30 M
# 3 30 400.4 DDD 4 90 F
# 4 50 500.5 EEE 5 150 M
R
df <- data.frame(X=x, Y=y, Z=z)
df$A <- 1:5
df
df$X3 <- df$X * 3
df
df$S <- rep(c("M","F"),length=5) # "M" "F" "M" "F" "M"
df[["S"]] <- rep(c("M","F"),length=5)
df[[6]] <- rep(c("M","F"),length=5)
df
# X Y Z A X3 S
# 1 20 100.1 AAA 1 60 M
# 2 40 200.2 BBB 2 120 F
# 3 10 300.3 CCC 3 30 M
# 4 30 400.4 DDD 4 90 F
# 5 50 500.5 EEE 5 150 M
transform(df, s=tolower(df$S))
# X Y Z A X3 S s
# 1 20 100.1 AAA 1 60 M m
# 2 40 200.2 BBB 2 120 F f
# 3 10 300.3 CCC 3 30 M m
# 4 30 400.4 DDD 4 90 F f
# 5 50 500.5 EEE 5 150 M m
transform()
はもとのデータフレームを変更しません。
SQL
SELECT X, Y, Z, X * 3 AS X3
FROM df;
SELECT
X,
Y,
Z,
CASE
WHEN S = "F" THEN NULL
ELSE A
END CASE AS A2
FROM
df
;
列名変更
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df.columns = ['xx','yy','zz']
df
print(df)
# xx yy zz
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
# 3 30 400.4 DDD
# 4 50 500.5 EEE
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df.rename(columns={'X':'xx','Y':'yy','Z':'zz'})
print(df.rename(columns={'X':'xx','Y':'yy','Z':'zz'}))
# xx yy zz
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
# 3 30 400.4 DDD
# 4 50 500.5 EEE
df.rename(columns={'X':'xx','Y':'yy','Z':'zz'}, inplace=True)
df
print(df)
# xx yy zz
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
# 3 30 400.4 DDD
# 4 50 500.5 EEE
R
df <- data.frame(X=x, Y=y, Z=z)
names(df) <- c("xx", "yy", "zz")
df
# xx yy zz
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
names(df)[2] <- "yyy"
df
# xx yyy zz
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
SQL
SELECT X AS xx, Y AS yy, Z AS zzz
FROM df;
列への代入
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df['Y'] = df['X'] / 1000
df
print(df)
# X Y Z
# 0 20 0.02 AAA
# 1 40 0.04 BBB
# 2 10 0.01 CCC
# 3 30 0.03 DDD
# 4 50 0.05 EEE
R
df <- data.frame(X=x, Y=y, Z=z)
df$Y <- df$X / 1000
df[["Y"]] <- df$X / 1000
df[[2]] <- df$X / 1000
df
# X Y Z
# 1 20 0.02 AAA
# 2 40 0.04 BBB
# 3 10 0.01 CCC
# 4 30 0.03 DDD
# 5 50 0.05 EEE
# 列の消去
df <- data.frame(X=x, Y=y, Z=z)
df$Y <- NULL
df[["Y"]] <- NULL
# df[[2]] <- NULL
df
# X Z
# 1 20 AAA
# 2 40 BBB
# 3 10 CCC
# 4 30 DDD
# 5 50 EEE
SQL
SELECT
X,
X / 100 AS Y,
Z
FROM
df;
行の条件抽出フィルタ
SQLのWHERE条件に相当する、条件を指定して行を抽出(フィルタ)する方法です。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df['X'] < 30
# 0 True
# 1 False
# 2 True
# 3 False
# 4 False
# Name: X, dtype: bool
type(df['X'] < 30)
# pandas.core.series.Series
df[df['X'] < 30]
print(df[df['X'] < 30])
df.loc[df['X'] < 30,:]
print(df.loc[df['X'] < 30,:])
df.query('X < 30')
print(df.query('X < 30'))
# X Y Z
# 0 20 100.1 AAA
# 2 10 300.3 CCC
(df['X'] > 10) & (df['X'] < 50)
# 0 True
# 1 True
# 2 False
# 3 True
# 4 False
# Name: X, dtype: bool
df[(df['X'] > 10) & (df['X'] < 50)]
print(df[(df['X'] > 10) & (df['X'] < 50)])
df.query('X > 10 & X < 50')
print(df.query('X > 10 & X < 50'))
df.query('10 < X < 50')
print(df.query('10 < X < 50'))
# X Y Z
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 3 30 400.4 DDD
R
df <- data.frame(X=x, Y=y, Z=z)
df$X < 30
# [1] TRUE FALSE TRUE FALSE FALSE
df[df$X < 30,]
# X Y Z
# 1 20 100.1 AAA
# 3 10 300.3 CCC
df$X > 10 & df$X < 50
# [1] TRUE TRUE FALSE TRUE FALSE
df[df$X > 10 & df$X < 50,]
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 4 30 400.4 DDD
SQL
SELECT *
FROM df
WHERE X < 30;
SELECT *
FROM df
WHERE X > 10 AND X < 50;
NAを1つでも含む行を除いて選択
Python
R
df <- data.frame(X=x, Y=y, Z=z)
df$S <- rep(c("M","F"),length=5)
df$s <- tolower(df$S)
df$X2 <- ifelse(df$S == "F", NA, df$X)
df$s2 <- ifelse(df$S == "F", NA, df$s)
df
# X Y Z S s X2 s2
# 1 20 100.1 AAA M m 20 m
# 2 40 200.2 BBB F f NA <NA>
# 3 10 300.3 CCC M m 10 m
# 4 30 400.4 DDD F f NA <NA>
# 5 50 500.5 EEE M m 50 m
na.omit(df)
subset(df, complete.cases(df))
df[complete.cases(df),]
# X Y Z S s X2 s2
# 1 20 100.1 AAA M m 20 m
# 3 10 300.3 CCC M m 10 m
# 5 50 500.5 EEE M m 50 m
SQL
行のソート
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df.sort_values(by='X')
print(df.sort_values(by='X'))
# X Y Z
# 2 10 300.3 CCC
# 0 20 100.1 AAA
# 3 30 400.4 DDD
# 1 40 200.2 BBB
# 4 50 500.5 EEE
df.sort_values(by='X', ascending=False)
print(df.sort_values(by='X', ascending=False))
# X Y Z
# 4 50 500.5 EEE
# 1 40 200.2 BBB
# 3 30 400.4 DDD
# 0 20 100.1 AAA
# 2 10 300.3 CCC
df['S'] = ['M','F','M','F','M']
df
print(df)
# X Y Z S
# 0 20 100.1 AAA M
# 1 40 200.2 BBB F
# 2 10 300.3 CCC M
# 3 30 400.4 DDD F
# 4 50 500.5 EEE M
df.sort_values(by=['S','X'])
print(df.sort_values(by=['S','X']))
# X Y Z S
# 3 30 400.4 DDD F
# 1 40 200.2 BBB F
# 2 10 300.3 CCC M
# 0 20 100.1 AAA M
# 4 50 500.5 EEE M
R
df <- data.frame(X=x, Y=y, Z=z)
order(df$X)
# [1] 3 1 4 2 5
df[order(df$X), ]
# X Y Z
# 3 10 300.3 CCC
# 1 20 100.1 AAA
# 4 30 400.4 DDD
# 2 40 200.2 BBB
# 5 50 500.5 EEE
order(df$X, decreasing = TRUE)
# [1] 5 2 4 1 3
df[order(df$X, decreasing = TRUE),]
# X Y Z
# 5 50 500.5 EEE
# 2 40 200.2 BBB
# 4 30 400.4 DDD
# 1 20 100.1 AAA
# 3 10 300.3 CCC
df <- data.frame(X=x, Y=y, Z=z)
df$S <- rep(c("M","F"),length=5)
df
# X Y Z S
# 1 20 100.1 AAA M
# 2 40 200.2 BBB F
# 3 10 300.3 CCC M
# 4 30 400.4 DDD F
# 5 50 500.5 EEE M
order(df$S, df$X)
# [1] 4 2 3 1 5
df[order(df$S, df$X), ]
# X Y Z S
# 4 30 400.4 DDD F
# 2 40 200.2 BBB F
# 3 10 300.3 CCC M
# 1 20 100.1 AAA M
# 5 50 500.5 EEE M
SQL
SELECT *
FROM df
ORDER BY X ASC;
SELECT *
FROM df
ORDER BY X DESC;
SELECT *
FROM df
ORDER BY S ASC, X ASC;
データフレームの集計
基本統計量
基本統計量(要約統計量)の表示です。
Python
データフレームのdescribe()
メソッドで基本統計量を表示できます。
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df
print(df)
# X Y Z
# 0 20 100.1 AAA
# 1 40 200.2 BBB
# 2 10 300.3 CCC
# 3 30 400.4 DDD
# 4 50 500.5 EEE
df.describe()
print(df.describe())
# X Y
# count 5.000000 5.000000
# mean 30.000000 300.300000
# std 15.811388 158.271997
# min 10.000000 100.100000
# 25% 20.000000 200.200000
# 50% 30.000000 300.300000
# 75% 40.000000 400.400000
# max 50.000000 500.500000
df.describe().T
print(df.describe().T)
# count mean std min 25% 50% 75% max
# X 5.0 30.0 15.811388 10.0 20.0 30.0 40.0 50.0
# Y 5.0 300.3 158.271997 100.1 200.2 300.3 400.4 500.5
type(df.describe())
# pandas.core.frame.DataFrame
結果は、8行(今の場合は8×2)のデータフレームが返ります。
df.describe().T
は転置して(2×8の形で)表示しているだけです。
R
summary()
でデータフレームのサマリーを表示できます。
df <- data.frame(X=x, Y=y, Z=z)
df
# X Y Z
# 1 20 100.1 AAA
# 2 40 200.2 BBB
# 3 10 300.3 CCC
# 4 30 400.4 DDD
# 5 50 500.5 EEE
summary(df)
# X Y Z
# Min. :10 Min. :100.1 AAA:1
# 1st Qu.:20 1st Qu.:200.2 BBB:1
# Median :30 Median :300.3 CCC:1
# Mean :30 Mean :300.3 DDD:1
# 3rd Qu.:40 3rd Qu.:400.4 EEE:1
# Max. :50 Max. :500.5
SQL
集計
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
df.count()
print(df.count())
# X 5
# Y 5
# Z 5
# S 5
# dtype: int64
type(df.count())
# pandas.core.series.Series
df.sum()
print(df.sum())
# X 150
# Y 1501.5
# Z AAABBBCCCDDDEEE
# S MFMFM
# dtype: object
df[['X','Y']].sum()
print(df[['X','Y']].sum())
# X 150.0
# Y 1501.5
# dtype: float64
df.mean()
print(df.mean())
# X 30.0
# Y 300.3
# dtype: float64
df.cumsum()
print(df.cumsum())
# X Y Z S
# 0 20 100.1 AAA M
# 1 60 300.3 AAABBB MF
# 2 70 600.6 AAABBBCCC MFM
# 3 100 1001.0 AAABBBCCCDDD MFMF
# 4 150 1501.5 AAABBBCCCDDDEEE MFMFM
df.cov()
print(df.cov())
# X Y
# X 250.00 1251.250
# Y 1251.25 25050.025
df.corr()
print(df.corr())
# X Y
# X 1.0 0.5
# Y 0.5 1.0
R
df <- data.frame(X=x, Y=y, Z=z)
# 行数のカウント
length(df[df$S == "F"])
# [1] 2
# 列ごとの統計量
colSums(df[,1:2])
# X Y
# 150.0 1501.5
colMeans(df[,1:2])
# X Y
# 30.0 300.3
var(df[,1:2])
# X Y
# X 250.00 1251.25
# Y 1251.25 25050.03
cov(df[,1:2])
# X Y
# X 250.00 1251.25
# Y 1251.25 25050.03
# クロス集計
df <- data.frame(X=x, Y=y, Z=z)
table(df[,c("X","Z")])
# Z
# X AAA BBB CCC DDD EEE
# 10 0 0 1 0 0
# 20 1 0 0 0 0
# 30 0 0 0 1 0
# 40 0 1 0 0 0
# 50 0 0 0 0 1
SQL
SELECT count(*), sum(X), sum(Y), mean(X), mean(Y)
FROM df;
グループ化
グループ化して集計についてです。
Python
df = pd.DataFrame({'X': x, 'Y': y, 'Z': z})
s = ['M','F','M','F','M']
df['S'] = s
df
print(df)
# X Y Z S
# 0 20 100.1 AAA M
# 1 40 200.2 BBB F
# 2 10 300.3 CCC M
# 3 30 400.4 DDD F
# 4 50 500.5 EEE M
# グループ化
df.groupby('S')
df.groupby('S').sum()
print(df.groupby('S').sum())
# X Y
# S
# F 70 600.6
# M 80 900.9
df.groupby('S').mean()
print(df.groupby('S').mean())
# X Y
# S
# F 35.000000 300.3
# M 26.666667 300.3
df.groupby(['S','Z'])
df.groupby(['S','Z']).sum()
print(df.groupby(['S','Z']).sum())
# X Y
# S Z
# F BBB 40 200.2
# DDD 30 400.4
# M AAA 20 100.1
# CCC 10 300.3
# EEE 50 500.5
df.groupby(['S','Z']).mean()
print(df.groupby(['S','Z']).mean())
# X Y
# S Z
# F BBB 40 200.2
# DDD 30 400.4
# M AAA 20 100.1
# CCC 10 300.3
# EEE 50 500.5
R
df <- data.frame(X=x, Y=y, Z=z)
s <- rep(c("M","F"),length=5)
df$S <- s
df
# X Y Z S
# 1 20 100.1 AAA M
# 2 40 200.2 BBB F
# 3 10 300.3 CCC M
# 4 30 400.4 DDD F
# 5 50 500.5 EEE M
by(df, df$S, summary)
# df$S: F
# X Y Z S
# Min. :30.0 Min. :200.2 AAA:0 Length:2
# 1st Qu.:32.5 1st Qu.:250.2 BBB:1 Class :character
# Median :35.0 Median :300.3 CCC:0 Mode :character
# Mean :35.0 Mean :300.3 DDD:1
# 3rd Qu.:37.5 3rd Qu.:350.4 EEE:0
# Max. :40.0 Max. :400.4
# ---------------------------------------------------------------------------------------
# df$S: M
# X Y Z S
# Min. :10.00 Min. :100.1 AAA:1 Length:3
# 1st Qu.:15.00 1st Qu.:200.2 BBB:0 Class :character
# Median :20.00 Median :300.3 CCC:1 Mode :character
# Mean :26.67 Mean :300.3 DDD:0
# 3rd Qu.:35.00 3rd Qu.:400.4 EEE:1
# Max. :50.00 Max. :500.5
SQL
SELECT sum(X), sum(Y), mean(X), mean(Y)
FROM df
GROUP BY S;
SELECT sum(X), sum(Y), mean(X), mean(Y)
FROM df
GROUP BY S, Z;
データフレームの結合
横に並べる
Python
k1 = np.arange(1,5+1)
k2 = np.array([1,3,5,1,3])
x1 = k1*10
x2 = k1*100
x3 = k1*1000
k1, k2, x1, x2, x3
# (array([1, 2, 3, 4, 5]),
# array([1, 3, 5, 1, 3]),
# array([10, 20, 30, 40, 50]),
# array([100, 200, 300, 400, 500]),
# array([1000, 2000, 3000, 4000, 5000]))
dfk1x1 = pd.DataFrame({'k1':k1, 'x1':x1})
dfk1x1
print(dfk1x1)
# k1 x1
# 0 1 10
# 1 2 20
# 2 3 30
# 3 4 40
# 4 5 50
dfk2x2 = pd.DataFrame({'k2':k2, 'x2':x2})
dfk2x2
print(dfk2x2)
# k2 x2
# 0 1 100
# 1 3 200
# 2 5 300
# 3 1 400
# 4 3 500
# 横に並べる
pd.concat([dfk1x1, dfk2x2], axis=1)
print(pd.concat([dfk1x1, dfk2x2], axis=1))
# k1 x1 k2 x2
# 0 1 10 1 100
# 1 2 20 3 200
# 2 3 30 5 300
# 3 4 40 1 400
# 4 5 50 3 500
R
k1 <- 1:5
k2 <- c(1,3,5,1,3)
x1 <- k1*10
x2 <- k1*100
x3 <- k1*1000
k1
# [1] 1 2 3 4 5
k2
# [1] 1 3 5 1 3
x1
# [1] 10 20 30 40 50
x2
# [1] 100 200 300 400 500
x3
# [1] 1000 2000 3000 4000 5000
dfk1x1 <- data.frame(k1, x1)
dfk1x1
# k1 x1
# 1 1 10
# 2 2 20
# 3 3 30
# 4 4 40
# 5 5 50
dfk2x2 <- data.frame(k2, x2)
dfk2x2
# k2 x2
# 1 1 100
# 2 3 200
# 3 5 300
# 4 1 400
# 5 3 500
# 横に並べる
data.frame(dfk1x1, dfk2x2)
# k1 x1 k2 x2
# 1 1 10 1 100
# 2 2 20 3 200
# 3 3 30 5 300
# 4 4 40 1 400
# 5 5 50 3 500
cbind(dfk1x1, dfk2x2)
# k1 x1 k2 x2
# 1 1 10 1 100
# 2 2 20 3 200
# 3 3 30 5 300
# 4 4 40 1 400
# 5 5 50 3 500
SQL
縦に並べる
データフレームを縦に並べます。SQLのUNIONの操作です。
Python
dfk2x2_2 = pd.DataFrame({'k1':k2, 'x1':x2})
dfk2x2_2
print(dfk2x2_2)
# k1 x1
# 0 1 100
# 1 3 200
# 2 5 300
# 3 1 400
# 4 3 500
# 縦に並べる
pd.concat([dfk1x1, dfk2x2_2], axis=0)
print(pd.concat([dfk1x1, dfk2x2_2], axis=0))
pd.concat([dfk1x1, dfk2x2_2])
print(pd.concat([dfk1x1, dfk2x2_2]))
dfk1x1.append(dfk2x2_2)
print(dfk1x1.append(dfk2x2_2))
# k1 x1
# 0 1 10
# 1 2 20
# 2 3 30
# 3 4 40
# 4 5 50
# 0 1 100
# 1 3 200
# 2 5 300
# 3 1 400
# 4 3 500
pd.concat([dfk1x1, dfk2x2_2], ignore_index=True)
print(pd.concat([dfk1x1, dfk2x2_2], ignore_index=True))
dfk1x1.append(dfk2x2_2, ignore_index=True)
print(dfk1x1.append(dfk2x2_2, ignore_index=True))
# k1 x1
# 0 1 10
# 1 2 20
# 2 3 30
# 3 4 40
# 4 5 50
# 5 1 100
# 6 3 200
# 7 5 300
# 8 1 400
# 9 3 500
横に並べるのに使ったconcat()
をaxis=0
(デフォルト)として使える他に、append()
が使えます。ignore_index=True
とするとインデックスがふり直されます。列名は一致させておく必要があります。
R
dfk2x2_2 <- data.frame(k1 = k2, x1 = x2)
dfk2x2_2
# k1 x1
# 1 1 100
# 2 3 200
# 3 5 300
# 4 1 400
# 5 3 500
# 縦に並べる
rbind(dfk1x1, dfk2x2_2)
# k1 x1
# 1 1 10
# 2 2 20
# 3 3 30
# 4 4 40
# 5 5 50
# 6 1 100
# 7 3 200
# 8 5 300
# 9 1 400
# 10 3 500
SQL
SELECT * FROM dfk1x1
UNION ALL
SELECT * FROM dfk2x2
;
キーで結合
SQLのジョインの操作です。
1つのキーで結合
Python
dfk1x2 = pd.DataFrame({'k':k1, 'x2':x2}).drop(2-1)
dfk1x2
print(dfk1x2)
# k x2
# 0 1 100
# 2 3 300
# 3 4 400
# 4 5 500
dfk1x3 = pd.DataFrame({'k':k1, 'x3':x3}).drop(3-1)
dfk1x3
print(dfk1x3)
# k x3
# 0 1 1000
# 1 2 2000
# 3 4 4000
# 4 5 5000
# 内部結合(INNER JOIN)
pd.merge(dfk1x2, dfk1x3, on='k')
print(pd.merge(dfk1x2, dfk1x3, on='k'))
pd.merge(dfk1x2, dfk1x3, on='k', how='inner')
print(pd.merge(dfk1x2, dfk1x3, on='k', how='inner'))
# k x2 x3
# 0 1 100 1000
# 1 4 400 4000
# 2 5 500 5000
# 左外部結合(LEFT OUTER JOIN)
pd.merge(dfk1x2, dfk1x3, on='k', how='left')
print(pd.merge(dfk1x2, dfk1x3, on='k', how='left'))
# k x2 x3
# 0 1 100 1000.0
# 1 3 300 NaN
# 2 4 400 4000.0
# 3 5 500 5000.0
# 右外部結合(RIGHT OUTER JOIN)
pd.merge(dfk1x2, dfk1x3, on='k', how='right')
print(pd.merge(dfk1x2, dfk1x3, on='k', how='right'))
# k x2 x3
# 0 1 100.0 1000
# 1 4 400.0 4000
# 2 5 500.0 5000
# 3 2 NaN 2000
# 完全外部結合(FULL OUTER JOIN)
pd.merge(dfk1x2, dfk1x3, on='k', how='outer')
print(pd.merge(dfk1x2, dfk1x3, on='k', how='outer'))
# k x2 x3
# 0 1 100.0 1000.0
# 1 3 300.0 NaN
# 2 4 400.0 4000.0
# 3 5 500.0 5000.0
# 4 2 NaN 2000.0
R
dfk1x2 <- data.frame(k1, x2)[-2,]
dfk1x2
# k1 x2
# 1 1 100
# 3 3 300
# 4 4 400
# 5 5 500
dfk1x3 <- data.frame(k1, x3)[-3,]
dfk1x3
# k1 x3
# 1 1 1000
# 2 2 2000
# 4 4 4000
# 5 5 5000
# 内部結合(INNER JOIN)
merge(dfk1x2, dfk1x3)
merge(dfk1x2, dfk1x3, by="k1")
merge(dfk1x2, dfk1x3, by="k1", sort=F) # ソートしない
# k1 x2 x3
# 1 1 100 1000
# 2 4 400 4000
# 3 5 500 5000
# 左外部結合(LEFT OUTER JOIN)
merge(dfk1x2, dfk1x3, by="k1", all.x=T)
# k1 x2 x3
# 1 1 100 1000
# 2 3 300 NA
# 3 4 400 4000
# 4 5 500 5000
# 右外部結合(RIGHT OUTER JOIN)
merge(dfk1x2, dfk1x3, by="k1", all.y=T)
# k1 x2 x3
# 1 1 100 1000
# 2 2 NA 2000
# 3 4 400 4000
# 4 5 500 5000
merge(dfk1x2, dfk1x3, by="k1", all.y=T, sort=F) # ソートしない
# k1 x2 x3
# 1 1 100 1000
# 2 4 400 4000
# 3 5 500 5000
# 4 2 NA 2000
# 完全外部結合(FULL OUTER JOIN)
merge(dfk1x2, dfk1x3, by="k1", all=T)
# k1 x2 x3
# 1 1 100 1000
# 2 2 NA 2000
# 3 3 300 NA
# 4 4 400 4000
# 5 5 500 5000
merge(dfk1x2, dfk1x3, by="k1", all=T, sort=F) # ソートしない
# k1 x2 x3
# 1 1 100 1000
# 2 4 400 4000
# 3 5 500 5000
# 4 3 300 NA
# 5 2 NA 2000
SQL
SELECT *
FROM dfk1x2 INNER JOIN dfk1x3 ON dfk1x2.k = dfk1x3.k
;
SELECT *
FROM dfk1x2 LEFT JOIN dfk1x3 ON dfk1x2.k = dfk1x3.k
;
SELECT *
FROM dfk1x2 RIGHT JOIN dfk1x3 ON dfk1x2.k = dfk1x3.k
;
SELECT *
FROM dfk1x2 FULL JOIN dfk1x3 ON dfk1x2.k = dfk1x3.k
;
名前の異なるキーで結合
Python
# 名前の異なるキーで結合
pd.merge(dfk1x1, dfk2x2, left_on='k1', right_on='k2', how='left')
print(pd.merge(dfk1x1, dfk2x2, left_on='k1', right_on='k2', how='left'))
# k1 x1 k2 x2
# 0 1 10 1.0 100.0
# 1 1 10 1.0 400.0
# 2 2 20 NaN NaN
# 3 3 30 3.0 200.0
# 4 3 30 3.0 500.0
# 5 4 40 NaN NaN
# 6 5 50 5.0 300.0
R
# 名前の異なるキーで結合
merge(dfk1x1, dfk2x2, by.x="k1", by.y="k2", all.x=T)
# k1 x1 x2
# 1 1 10 100
# 2 1 10 400
# 3 2 20 NA
# 4 3 30 200
# 5 3 30 500
# 6 4 40 NA
# 7 5 50 300
SQL
SELECT *
FROM dfk1x1 LEFT JOIN dfk2x2 ON dfk1x1.k1 = dfk2x2.k2
;
複数のキーで結合
Python
# 複数のキーで結合
dfk1k2x2 = pd.DataFrame({'k1':k1, 'k2':k2, 'x2':x2}).drop(2-1)
dfk1k2x2
print(dfk1k2x2)
# k1 k2 x2
# 0 1 1 100
# 2 3 5 300
# 3 4 1 400
# 4 5 3 500
dfk1k2x3 = pd.DataFrame({'k1':k1, 'k2':k2, 'x3':x3}).drop(3-1)
dfk1k2x3
print(dfk1k2x3)
# k1 k2 x3
# 0 1 1 1000
# 1 2 3 2000
# 3 4 1 4000
# 4 5 3 5000
pd.merge(dfk1k2x2, dfk1k2x3, on=['k1','k2'], how='left')
print(pd.merge(dfk1k2x2, dfk1k2x3, on=['k1','k2'], how='left'))
# k1 k2 x2 x3
# 0 1 1 100 1000.0
# 1 3 5 300 NaN
# 2 4 1 400 4000.0
# 3 5 3 500 5000.0
dfk1k2x2.merge(dfk1k2x3, on=['k1','k2'], how='left')
print(dfk1k2x2.merge(dfk1k2x3, on=['k1','k2'], how='left'))
# k1 k2 x2 x3
# 0 1 1 100 1000.0
# 1 3 5 300 NaN
# 2 4 1 400 4000.0
# 3 5 3 500 5000.0
最後の例ように、pd.merge(dfx, dfy, ...)
をdfx.merge(dfy, ...)
の形にも書くこともできます。他の上の例も同様です。
R
# 複数のキーで結合
dfk1k2x2 <- data.frame(k1, k2, x2)[-2,]
dfk1k2x2
# k1 k2 x2
# 1 1 1 100
# 3 3 5 300
# 4 4 1 400
# 5 5 3 500
dfk1k2x3 <- data.frame(k1, k2, x3)[-3,]
dfk1k2x3
# k1 k2 x3
# 1 1 1 1000
# 2 2 3 2000
# 4 4 1 4000
# 5 5 3 5000
merge(dfk1k2x2, dfk1k2x3, by=c("k1","k2"), all.x=T)
# k1 k2 x2 x3
# 1 1 1 100 1000
# 2 3 5 300 NA
# 3 4 1 400 4000
# 4 5 3 500 5000
SQL
SELECT *
FROM dfk1k2x2 LEFT JOIN dfk1k2x3
ON dfk1k2x2.k1 = dfk1k2x3.k1 AND
dfk1k2x2.k2 = dfk1k2x3.k2
;
その他
Python
R
attach(df)
としておくと、X
だけでdf$X
にアクセスできるようになります。元に戻すには、detach(df)
とします。
# attachとdetach
df <- data.frame(X=x, Y=y, Z=z)
df$S <- rep(c("M","F"),length=5)
attach(df)
X
# [1] 2 4 1 3 5
S
# [1] "M" "F" "M" "F" "M"
detach(df)
SQL
長くなってしまいましたので、Rのdplyr
パッケージについては別記事にします。
まとめ
一覧
各言語で使用する関数等を一覧にまとめます。(比較のために、EXCELでの計算も示しました。)
Python(pandas) | R | RDB(Access) | Excel | 行列 | |
---|---|---|---|---|---|
オブジェクト | DataFrame | data.frame | テーブル | テーブル | 行列(matrix) |
行 | index(axis=0) | 行(row) | レコード | 行(ROW) | 行(row) |
列 | columns(axis=1) | 列(col) | フィールド | 列(COLUMN) | 列(column) |
要素 | values | 値 | CELL | 要素 | |
列の正体 | pandasのSeries | ベクトル | 同じデータ型の値 |
データフレームdf
||X|Y|Z|
|--:|:-:|:-:|:-:|:-:|
|1|20|100.1|AAA|
|2|40|200.2|BBB|
|3|10|300.3|CCC|
|4|30|400.4|DDD|
|5|50|500.5|EEE|
データフレームの作成
Python(pandas) | R | SQL | |
---|---|---|---|
データフレームの作成 |
pd.DataFrame({ 'X': x, 'Y': y, 'Z': z})
|
data.frame( X = x, Y = y, Z = z)
|
CREATE TABLE |
データフレームの属性
Python(pandas) | R | SQL | 結果 | |
---|---|---|---|---|
クラス | type(df) |
class(df) |
||
構造 | df.info() |
str(df) |
||
列 |
df.columns df.columns.values
|
names(df) colnames(df)
|
'X', 'Y', 'Z' | |
行 |
df.index df.index.values
|
rownames(df) row.names(df)
|
||
値 | df.values |
|||
列数 | len(df.columns) |
length(df) ncol(df)
|
3 | |
行数 |
len(df.index) len(df)
|
nrow(df) |
5 | |
形(行数, 列数) | df.shape |
dim(df) |
(5, 3) | |
全要素数 | df.size |
15=5*3 | ||
注意)pandasのlen() は行数に、Rのdata.frameのlength() は列数。 |
データフレームへのアクセス
Python(pandas) | R | SQL | 結果 | |
---|---|---|---|---|
列ベクトル |
df.X df['X']
|
df$X df[["X"]] df[[1]]
|
ベクトル (20,40, 10,30,50) |
|
列指定 |
df[['X']] df.loc[:,['X']]
|
df[1] df["X"]
|
SELECT X FROM df;
|
データフレーム |
複数列指定 |
df[['X','Z']] df.loc[:,['X','Z']] df.iloc[:, [1-1,3-1]]
|
df[c(1,3)] df[c("X","Z")]
|
SELECT Z, X FROM df; |
データフレーム |
df[['Z','Y','X']] df.loc[:, ['Z','Y','X']] df.iloc[:, [3-1,2-1,1-1]]
|
df[c(3,1,2)] df[c("Z","X","Y")]
|
SELECT Z, X, Y FROM df; |
データフレーム | |
先頭n行 | df.head(n) |
head(df, n) |
データフレーム | |
末尾n行 | df.tail(n) |
tail(df, n) |
データフレーム | |
要素 |
df.iat[1-1,1-1] df.at[1-1,'X'] df.iloc[1-1,1-1] df.loc[1-1,'X'] df['X'][1-1] df.X[1-1]
|
df[1,1] df[1,"X"] df[[1,1]] df[[1,"X"]] df$X[1] df[["X"]][1]
|
値 20 |
|
複数行・複数列指定 |
df.iloc[ [1-1,3-1],[1-1,3-1]] df.loc[ [1-1,3-1],['X','Z']]
|
df[c(1,3),c(1,3)] df[c(1,3),c("X","Z")] df[c(T,F,T,F,F), c(T,F,T)]
|
データフレーム | |
複数列指定 |
df.iloc[:,[1-1,3-1]] df.loc[:,['X','Z']] df[['X','Z']]
|
df[,c(1,3)] df[,c("X","Z")] df[,c(T,F,T)]
|
データフレーム | |
複数行指定 |
df.iloc[[1-1,3-1],:] df.loc[[1-1,3-1],:] df.iloc[[1-1,3-1]] df.loc[[1-1,3-1]]
|
df[c(1,3),] df[c(T,F,T,F,F),]
|
データフレーム | |
注意) |
データフレームの操作
Python(pandas) | R | SQL | |
---|---|---|---|
列の選択 | df[['Z','Y','X']] |
df[c("Z","X","Y")] |
SELECT Z, X, Y FROM df;
|
列の追加 | df['X3'] = df['X'] * 3 |
df$X3 <- df$X * 3 |
SELECT X, Y, Z, X * 3 AS X3 FROM df;
|
列名変更 |
df.rename( columns={'X':'xx', 'Y':'yy', 'Z':'zz'})
|
names(df) <- c("xx", "yy", "zz")
|
SELECT X AS xx, Y AS yy, Z AS zzz FROM df;
|
行の条件抽出フィルタ |
df['X'] < 30 df.query('X < 30')
|
df[df$X < 30,] |
SELECT * FROM df WHERE X < 30;
|
df[(df['X'] > 10) & (df['X'] < 50)] df.query('10 < X < 50')
|
df[df$X > 10 & df$X < 50,]
|
SELECT * FROM df WHERE X > 10 AND X < 50;
|
|
行のソート | df.sort_values(by='X') |
df[order(df$X), ] |
SELECT * FROM df ORDER BY X ASC;
|
行のソート | df.sort_values(by='X', ascending=False) |
df[order(df$X, decreasing = TRUE),] |
SELECT * FROM df ORDER BY X DESC;
|
行のソート | df.sort_values(by=['S','X']) |
df[order(df$S, df$X), ] |
SELECT * FROM df ORDER BY S ASC, X ASC;
|
データフレームの集計
Python(pandas) | R | SQL | |
---|---|---|---|
基本統計量 |
df.describe() df.describe().T
|
summary(df) |
|
グループ化 | df.groupby('S') |
GROUP BY S; |
|
グループ化 | df.groupby(['S','Z']) |
GROUP BY S, Z; |
データフレームの結合
Python(pandas) | R | SQL | |
---|---|---|---|
横に並べる |
pd.concat([df1, df2], axis=1)
|
cbind(df1, df2) |
|
縦に並べる |
pd.concat([df1, df2], axis=0) pd.concat([df1, df2], ignore_index=True) df1.append(df2, ignore_index=True)
|
rbind(df1, df2) |
UNION ALL |
内部結合 (INNER JOIN) |
pd.merge(df1, df2, on='k') pd.merge(df1, df2, on='k', how='inner')
|
merge(df1, df2) merge(df1, df2, by="k")
|
FROM df1 INNER JOIN df2 ON df1.k = df2.k
|
左外部結合 (LEFT OUTER JOIN) |
pd.merge(df1, df2, on='k', how='left')
|
merge(df1, df2, by="k", all.x=T)
|
FROM df1 LEFT JOIN df2 ON df1.k = df2.k
|
右外部結合 (RIGHT OUTER JOIN) |
pd.merge(df1, df2, on='k', how='right')
|
merge(df1, df2, by="k", all.y=T)
|
FROM df1 RIGHT JOIN df2 ON df1.k = df2.k
|
完全外部結合 (FULL OUTER JOIN) |
pd.merge(df1, df2, on='k', how='outer')
|
merge(df1, df2, by="k", all=T)
|
FROM df1 FULL JOIN df2 ON df1.k = df2.k
|
名前の異なるキーで結合 |
pd.merge(df1, df2, left_on='k1', right_on='k2', how='left')
|
merge(df1, df2, by.x="k1", by.y="k2", all.x=T)
|
FROM df1 LEFT JOIN df2 ON df1.k1 = df2.k2
|
複数のキーで結合 |
pd.merge(df1, df2, on=['k1','k2'], how='left')
|
merge(df1, df2, by=c("k1","k2"), all.x=T)
|
FROM df2 LEFT JOIN df2 ON df1.k1 = df2.k1 AND df1.k2 = df2.k2
|
長くなってしまいましたので、Rのdplyr
パッケージについては別記事にします。
プログラム全体
参考までに使ったプログラムの全体を示します。
(今回は長くなったので省略します。)
Python
R
VBA
参考
- Python
- R