28
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Excel的にPandasを使う] pandas DataFrameのテクニックまとめ

Last updated at Posted at 2018-07-25

もう、Excel的な集計はPythonでやってしまいたい。慣れるとそのほうが早いし便利ですね。
その時に、いつも調べてしまうような、よく使うテクニックをまとめてみました。

1.[基本処理] ファイル読み込み・出力

CSV読み込み

path='./path/to/csv'
df = pd.read_csv(path)

dataset = pd.read_csv(path,encoding='shift-jis') ## ExcelCSVの場合

dataset = pd.read_csv(path, index_col=2)    # indexを指定して

TSV読み込み

dataset = pd.read_table(path)

ファイル出力

df.to_csv(path)

2.[Excel的な基本編集]データ抽出・フィルタ(行・列)&フィルタ後のデータ更新

Excelでいう基本操作の行や列の追加、フィルタや関数による条件に応じた値代入など

カラム(列)抽出

df[ ['col1','col2','col3'] ] # 列名で抽出

カラム追加・削除

df['new_column'] = 0  # 初期値を0で埋めて追加

df.drop("new_column", axis=1)  # 列(axis=1)を指定して削除

行フィルタ・抽出・削除

df[df['product']=='P1'] # 条件で抽出

df.drop(5) # 行5を削除
df.drop([5,6]) # 行5,6を削除

列の値代入・更新

# =A1*2 的な
s = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

s.apply(lambda x: x * 2)
# a    2
# b    4
# c    6
# dtype: int64

# =IF(A1>0,1,0)的な
Y = df['flg'].apply( lambda x: 1 if x>0 else 0)

一気に更新 ( =A1+5 )

df['point'] += 5

条件を指定して更新 ( Excel関数の代替 ( =IF(A1>=5,'P1','P2' ) )

df.loc[ df['file_name'].str.contains('ABCD' ) ,'product'] = 'P1'    # 任意の文字列を含む場合

df.loc[ df['point'] >= 5 ,'product'] = 'P1'    #任意の条件に一致する場合

複数の要素を指定して更新


df.loc['Bob':'Dave', 'age'] = 25    # Bob ~ Daveまで一気に更新
df.loc['Bob':'Dave', 'age'] = [20, 30, 40]    #こんな風にもできる
df.iloc[1:3, 'age'] = 25        # 1 ~ 3まで一気に更新
df.loc[:'Dave', 'age'] = 25     # Daveまで一気に更新
df.loc[:5, 'age'] = 25          # 5まで一気に更新

df.iloc[::2, 0]    # 奇数行

df.iloc[1::2, 0]    # 偶数行

合計・平均,カウント( =sum(A:A) , =average(A:A) )

# mean は数値型のみ集約
df.mean()
# C2    2
# C3    5
# dtype: float64

# sum は 文字列も集約
df.sum()
# C1    ABC
# C2      6
# C3     15
# dtype: object

# sumif , subtotal的に ( =sumif() ,=subtotal(9, A:A) )
df[df['price']>=500].sum()

# count , counif
df.count()
df[df['price']>=500].count()

参考:http://sinhrks.hatenablog.com/entry/2014/11/27/232150


# 不偏標準偏差
df.std()
# C1    1.290994
# C2    1.290994
# C3    0.577350
# dtype: float64

# 標本標準偏差
df.std(ddof=False)

セルの値代入

df.at['Bob', 'age'] = 25    #index名で指定する場合
df.loc['Bob', 'age'] = 25   # locでも可能だが、1つの値更新は、atの方が早い
df.iat[1,0] = 25    # 行番号、列番号で指定(*いずれも0始まり)
df.iloc[1,0] = 25    # ilocでも可能だが、1つの値更新は、iatの方が早い

参考:pandasで任意の位置の値を取得・変更するat, iat, loc, iloc
https://note.nkmk.me/python-pandas-at-iat-loc-iloc/


3.[Excel VBA的な]ループ処理でなんでも自在に


1行ずつ処理

import pandas as pd
df = pd.DataFrame([[1, 10], [2, 20], [3, 30], [4, 40]], columns=['col1', 'col2'])
 
for index, row in df.iterrows():
    print(row['col1'], row['col2’])

値を更新する

for index, row in df.iterrows():
    row.point += 5
for index, row in df.iterrows():
    df.at[index, 'point'] += 5

まとめて取得

for age, point in zip(df['age'], df['point']):
    print(age)
    print(point)
    print('======\n')

1列ずつ処理


import pandas as pd
df = pd.DataFrame([[1, 10], [2, 20], [3, 30], [4, 40]], columns=['col1', 'col2'])
 
for index, col in df.iteritems():
    print(sum(col))

4.PivotTable的な集計

df = pd.DataFrame({'group': ['g1', 'g2', 'g1', 'g2'],
                   'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, 
                  columns=['group', 'A', 'B'])
df
#   group  A  B
# 0    g1  1  5
# 1    g2  2  6
# 2    g1  3  7
# 3    g2  4  8

grouped = df.groupby('group')

for name, group in grouped:
    print(name)
    print(group)
    print('')
# g1
#   group  A  B
# 0    g1  1  5
# 2    g1  3  7
# 
# g2
#   group  A  B
# 1    g2  2  6
# 3    g2  4  8

pivot_table()を使うともっと簡単。

pvTbl = pd.pivot_table(df,values=['A','B'],index='group',aggfunc='sum')
# values : 集計対象のカラムを指定、list or str
# index : 集計キー(list or str)
# aggfunc : mean , sum など集計方法を指定

pvTbl.reset_index(inplace=True)  # 元の状態だと 集計キーをdataFrameのindexとして使用できないため、indexを解除)

参考:https://deepage.net/features/pandas-pivot.html#%E3%83%94%E3%83%9C%E3%83%83%E3%83%88%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B


さっとグループごとの平均を計算

grouped = df.groupby('group')
grouped.apply(np.mean)
#        A  B
# group      
# g1     2  6
# g2     3  7

5.データ連結 (Hlookup, Vlookup的な)


行(縦)方向に連結

pd.concat([df1, df2 (,・・・)])

df1.append(df2)
df1.append([df2, df4])

1行だけ追加も同じように

s1 = pd.Series(['X0', 'X1', 'X2', 'X3'],
               index=['A', 'B', 'C', 'D'], name=10)    # nameはラベル名
df1.append(s1)

*列名が異なる場合は、一方がNaNで埋められる


横方向の連結

pd.concat([df1, df4], axis=1)

pd.concat([df1, df4], axis=1, join='inner')          # inner join的な(共通indexのみ)
pd.concat([df1, df4], axis=1, join_axes=[df1.index]) # left join的な

横方向の連結(Vlookup的な 厳密にはjoin的な)

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                     'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key': ['K1', 'K3', 'K5', 'K7'],
                      'C': ['C1', 'C3', 'C5', 'C7'],
                      'D': ['D1', 'D3', 'D5', 'D7']},
                     index=[1, 3, 5, 7])
pd.merge(left, right, on='key', how='left’)    # how: inner / left / right / outer
pd.merge(left, right, on=['key1', 'key2'])    # 複数のキーによる結合も

参考:http://sinhrks.hatenablog.com/entry/2015/01/28/073327

その他:pivot_tableで集計してjoinする方法は以下を参照
 https://teratail.com/questions/129198


6.統計処理


基本統計量

df.describe()

パーセンタイル(デシル)

def decile(pddata,targetCol,Sep=10,makeCol='decile'):
    pd['decile'] = pd.qcut(pddata[targetCol], Sep, labels=np.arange(Sep, 0, -1))
    return pd

相関行列

df.corr()
28
49
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?