Python データサイエンス

Python - PandasでDataFrameを操る魔術をまとめてみた

Pandasを使うとPythonでデータをテーブルみたいに扱えるようになる。集計したり、解析したりするのが楽ちんに!DataFrameのきめ細かな操作方法がなかなか覚えにくいのでチートシート用メモです!順次更新予定です!

とりあえずDataFrame形式のデータを作ってみる

# -*- coding: utf-8 -*-
import pandas as pd

"""
とりあえずDataFrame形式のデータを作ってみる
以下のようなデータを生成
             A      B      C
Tokyo    100.0  200.0  300.0
Osaka     10.0   20.0   30.0
Okinawa    1.5    2.5    3.5
"""
sample_df = pd.DataFrame([[100, 200, 300], [10, 20, 30], [1.5, 2.5, 3.5]],
        index = ['Tokyo', 'Osaka', 'Okinawa'], columns = ["A", "B", "C"])

print(sample_df)

DataFrameの構造を確認

  • 行数
  • 次元数
  • 基礎情報
  • 基礎統計量
"""
DataFrameの構造を確認
- 行数
- 次元数
- 基礎情報
- 基礎統計量
"""
sample_df_len = len(sample_df)
sample_df_shape = sample_df.shape
sample_df_info = sample_df.info
sample_df_describe = sample_df.describe()
print(sample_df_len)
print(sample_df_shape)
print(sample_df_info)
print(sample_df_describe)

データへのアクセス

カラムやインデックスにアクセス

"""
カラムやインデックスにアクセス
Indexオブジェクトが返ってくる
Index(['A', 'B', 'C'], dtype='object')
Index(['Tokyo', 'Osaka', 'Okinawa'], dtype='object')
"""
sample_df_columns = sample_df.columns
sample_df_index = sample_df.index
print(sample_df_columns)
print(sample_df_index)

カラム名を指定してアクセス

"""
カラム名を指定してアクセス
seriesオブジェクトが返ってくる

tokyo      100.0
osaka       10.0
okinawa      1.5
name: a, dtype: float64
<class 'pandas.core.series.series'>
"""
sample_a_series = sample_df["a"]
print(type(sample_a_series))

カラム名を複数指定してアクセス

"""
カラム名を複数指定してアクセス
DataFrameオブジェクトが返ってくる

             A      B
Tokyo    100.0  200.0
Osaka     10.0   20.0
Okinawa    1.5    2.5
<class 'pandas.core.frame.DataFrame'>
"""
sample_a_b_df = sample_df[["A", "B"]]
print(type(sample_a_b_df))

インデックスを指定してアクセス

"""
インデックス名を指定してアクセス
ixで指定する必要がある
Seriesオブジェクトが返ってくる

a    100.0
b    200.0
c    300.0
name: tokyo, dtype: float64
<class 'pandas.core.series.series'>
"""
sample_tokyo_series = sample_df.ix["tokyo"]
print(type(sample_tokyo_series))

インデックスを複数指定してアクセス

"""
インデックス名を複数指定してアクセス
DataFrameオブジェクトが返ってくる
             A      B      C
Tokyo    100.0  200.0  300.0
Okinawa    1.5    2.5    3.5
<class 'pandas.core.frame.DataFrame'>
"""
sample_tokyo_okinawa_df = sample_df.ix[["Tokyo", "Okinawa"]]
print(type(sample_tokyo_okinawa_df))

特定の区間を番号で指定して抽出

"""
特定の区間を番号で指定して抽出
iloc[rows番号, columns番号]の形で書く
TokyoからOsakaまでのBからCまでのデータを取得
           B      C
Tokyo  200.0  300.0
Osaka   20.0   30.0
"""
sample_tokyo_osaka_b_c_df = sample_df.iloc[0:2 , 1:3]
print(sample_tokyo_osaka_b_c_df)

DataFrameを1行ずつfor文でループさせる

"""
DataFrameを1行ずつfor文でループさせる
Tokyo
A    100.0
B    200.0
C    300.0
Name: Tokyo, dtype: float64
Osaka
A    10.0
B    20.0
C    30.0
Name: Osaka, dtype: float64
Okinawa
A    1.5
B    2.5
C    3.5
Name: Okinawa, dtype: float64
"""
for index, cols in sample_df.iterrows():
    print(index)
    print(cols)

indexを書き換える

"""
indexの書き換え
"""
sample_df.index = ["TokyoA", "OsakaB", "OsakaC"]
print(sample_df)
sample_df.index = ["Tokyo", "Osaka", "Osaka"]
print(sample_df)

DataFrameのシャローコピーとディープコピー

詳細は、「PandasでDataFrame型をコピーする際はシャローとディープの違いに注意 | Miningoo」に書きました!

"""
DataFrameのシャローコピーとディープコピー
"""
print("DataFrameのシャローコピーとディープコピー")
sample_df_shallow = sample_df
sample_df_deep = sample_df.copy()
print("sample_df: ")
print(sample_df)
print("shallow: ")
print(sample_df_shallow)
print("deep: ")
print(sample_df_deep)
sample_df["A"]["Tokyo"] = 50.0
print("sample_df: ")
print(sample_df)
print("shallow: ")
print(sample_df_shallow)
print("deep: ")
print(sample_df_deep)

データの正規化

正規化の代表的な手法 z-score normalization と min-max normalization | Miningoo

"""
1. z-score normalization
以下の式で変換
x_new = (x - x_mean) / x_std
外れ値にもロバスト
"""
print("z-score normalization")
standardized_sample_df = (sample_df - sample_df.mean()) / sample_df.std()
print(standardized_sample_df)

"""
2. min-max normalization
以下の式で0から1になるように変換
x_new = (x - x_min) / (x_max - x_min)
minとmaxに強く影響をされてしまう
"""
print("min-max normalization")
normalized_sample_df = (sample_df - sample_df.min()) / (sample_df.max() - sample_df.min())
print(normalized_sample_df)

最後にコードをまとめると

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd

"""
とりあえずDataFrame形式のデータを作ってみる
以下のようなデータを生成
             A      B      C
Tokyo    100.0  200.0  300.0
Osaka     10.0   20.0   30.0
Okinawa    1.5    2.5    3.5
"""
sample_df = pd.DataFrame([[100, 200, 300], [10, 20, 30], [1.5, 2.5, 3.5]],
        index = ['Tokyo', 'Osaka', 'Okinawa'], columns = ["A", "B", "C"])
print("とりあえずDataFrame形式のデータを作ってみる")
print(sample_df)
print("")

"""
DataFrameの構造を確認
- 行数
- 次元数
- カラム情報
- 基礎統計量
  - count
  - mean
  - std
  - min
  - 25%
  - 50%
  - 75%
  - max
"""
print("DataFrameの構造を確認")
sample_df_len = len(sample_df)
sample_df_shape = sample_df.shape
sample_df_info = sample_df.info
sample_df_describe = sample_df.describe()
print(sample_df_len)
print(sample_df_shape)
print(sample_df_info)
print(sample_df_describe)
print("")

"""
カラムやインデックスにアクセス
Indexオブジェクトが返ってくる
Index(['A', 'B', 'C'], dtype='object')
Index(['Tokyo', 'Osaka', 'Okinawa'], dtype='object')
"""
print("カラムやインデックスにアクセス")
sample_df_columns = sample_df.columns
sample_df_index = sample_df.index
print(sample_df_columns)
print(sample_df_index)
print("")

"""
カラム名を指定してアクセス
Seriesオブジェクトが返ってくる

Tokyo      100.0
Osaka       10.0
Okinawa      1.5
Name: A, dtype: float64
<class 'pandas.core.series.Series'>
"""
print("カラム名を指定してアクセス")
sample_a_series = sample_df["A"]
print(type(sample_a_series))
print("")

"""
カラム名を複数指定してアクセス
DataFrameオブジェクトが返ってくる

             A      B
Tokyo    100.0  200.0
Osaka     10.0   20.0
Okinawa    1.5    2.5
<class 'pandas.core.frame.DataFrame'>
"""
print("カラム名を複数指定してアクセス")
sample_a_b_df = sample_df[["A", "B"]]
print(type(sample_a_b_df))
print("")

"""
インデックス名を指定してアクセス
ixで指定する必要がある
Seriesオブジェクトが返ってくる

A    100.0
B    200.0
C    300.0
Name: Tokyo, dtype: float64
<class 'pandas.core.series.Series'>
"""
print("インデックス名を指定してアクセス")
sample_tokyo_series = sample_df.ix["Tokyo"]
print(type(sample_tokyo_series))
print("")

"""
インデックス名を複数指定してアクセス
DataFrameオブジェクトが返ってくる
             A      B      C
Tokyo    100.0  200.0  300.0
Okinawa    1.5    2.5    3.5
<class 'pandas.core.frame.DataFrame'>
"""
print("インデックス名を複数指定してアクセス")
sample_tokyo_okinawa_df = sample_df.ix[["Tokyo", "Okinawa"]]
print(type(sample_tokyo_okinawa_df))
print("")

"""
特定の区間を番号で指定して抽出
iloc[rows番号, columns番号]の形で書く
TokyoからOsakaまでのBからCまでのデータを取得
           B      C
Tokyo  200.0  300.0
Osaka   20.0   30.0
"""
print("特定の区間を番号で指定して抽出")
sample_tokyo_osaka_b_c_df = sample_df.iloc[0:2 , 1:3]
print(sample_tokyo_osaka_b_c_df)
print("")

"""
indexの書き換え
"""
sample_df.index = ["TokyoA", "OsakaB", "OsakaC"]
print(sample_df)
sample_df.index = ["Tokyo", "Osaka", "Osaka"]
print(sample_df)
print("")

"""
DataFrameを1行ずつfor文でループさせる
Tokyo
A    100.0
B    200.0
C    300.0
Name: Tokyo, dtype: float64
Osaka
A    10.0
B    20.0
C    30.0
Name: Osaka, dtype: float64
Okinawa
A    1.5
B    2.5
C    3.5
Name: Okinawa, dtype: float64
"""
print("DataFrameを1行ずつfor文でループさせる")
for index, cols in sample_df.iterrows():
    print(index)
    print(cols)
print("")

"""
DataFrameのシャローコピーとディープコピー
"""
print("DataFrameのシャローコピーとディープコピー")
sample_df_shallow = sample_df
sample_df_deep = sample_df.copy()
print("sample_df: ")
print(sample_df)
print("shallow: ")
print(sample_df_shallow)
print("deep: ")
print(sample_df_deep)
sample_df["A"]["Tokyo"] = 50.0
print("sample_df: ")
print(sample_df)
print("shallow: ")
print(sample_df_shallow)
print("deep: ")
print(sample_df_deep)
print("")

"""
1. z-score normalization
以下の式で変換
x_new = (x - x_mean) / x_std
外れ値にもロバスト
"""
print("z-score normalization")
standardized_sample_df = (sample_df - sample_df.mean()) / sample_df.std()
print(standardized_sample_df)
print("")

"""
2. min-max normalization
以下の式で0から1になるように変換
x_new = (x - x_min) / (x_max - x_min)
minとmaxに強く影響をされてしまう
"""
print("min-max normalization")
normalized_sample_df = (sample_df - sample_df.min()) / (sample_df.max() - sample_df.min())
print(normalized_sample_df)
print("")

-Python, データサイエンス