[Python]Pandas Tips

Python

データフレーム作成

df = pd.DataFrame()

df = pd.DataFrame({
          'col1': [], 
          'col2': [],
          'col3': []})

データの追加

df = pd.DataFrame({
    'band_A': [], 
    'band_B': []
})

# 新しいデータを追加
new_data = {
    'band_A': 1, 
    'band_B': 2
}

df = df.append(new_data, ignore_index=True)

groupby

groupbyは指定したカラムごとに、何かのアクションを実行する関数です。groupbyを見かけたら、「○○カラムごとにを○○をする」と解釈すると、コードが読みやすくなります。

あるカラムに対して、要素ごとに個数をカウントします。

df_a = df[['id', 'name']].groupby('name').count().sort_values('id') # nameの個数をカウント
df_a = df_a.reset_index() # インデックスをカラム化
df_a = df_a.rename(columns={'id': 'count'})

指定したカラムの値が同じ行ごとに、actionカラムを加算しています。

df = pd.DataFrame({
          'item_x': [0, 1, 1],
          'item_y': [0, 1, 1],
          'action': [0, 2, 5]})
df = df.groupby(['item_x','item_y']).action.sum()

>>>df
item_x  item_y  
0      0        0
1      1        7

通し番号(cumcount)

groupbyで指定したカラムの値ごとに、通し番号を振ります。
ここでは、groupbyの後に、カラムを指定していますが、何の意味があるのかわかりません。無くても良い?

df = pd.DataFrame({
          'item_x': [0, 1, 1, 1, 2, 2, 3],
          'item_y': [0, 1, 1, 2, 2, 3, 4]})
df['n'] = df.groupby('item_x').item_y.cumcount()
# df['n'] = df.groupby('item_x').cumcount() # これでも良い?

>>>df
   item_x  item_y  n
0      0      0  0
1      1      1  0
2      1      1  1
3      1      2  2
4      2      2  0
5      2      3  1
6      3      4  0
df = pd.DataFrame({
          'item_x': [0, 1, 1, 1, 2, 2, 3],
          'item_y': [0, 1, 1, 2, 3, 3, 3]})
df['n'] = df.groupby('item_y').item_x.cumcount()

>>>df
   item_x item_y  n
0      0      0  0
1      1      1  0
2      1      1  1
3      1      2  0
4      2      3  0
5      2      3  1
6      3      3  2

使いどころとしては、タイムスタンプを降順でを並び替えをした後に、通し番号を付け、通し番号が30以下のデータを残すようにすると、日付が新しい30個のデータを残すことができます。

df = df.sort_values(['group','ts'],ascending=[True,False]) # ts(タイムスタンプ)を降順で並び替え
df = df.reset_index(drop=True)
df['n'] = df.groupby('group').cumcount() # 各グループごとに連番を設定
df = df.loc[df.n<30].drop('n',axis=1) # nが30以下のものを残して、nカラムを削除(なるべく日時が最新のものを使用)

条件抽出

df_a = df.loc[(df['id'] < 15) & (df['id'] > 1)]

df = df.loc[df['name'].isin(name_list)]

結合

appendする際、イコールで結ばないと元のデータフレームが変わらないので、注意。

df = df.append(df_cur)

列削除

df = df.drop('Unnamed: 0', axis=1)

カラム名変更

df_0 = df.rename(columns={'A': 'B'}, index={'C': 'D'})

データ生成

df['id'].values
>>> リストが返る

df['id']
>>> Seriesが返る

df[['id']]
>>> データフレームが返る

merge

idカラムをもとに、nameの情報をマージしたい場合を考えます。
innerはどちらかどちらのデータフレームに存在するidのみの行を残します。outerはすべて足し合わせて、足りないところはNaNで埋めます。rightも足し合わせますが、NaNの行は残しません。

a = pd.DataFrame({
          'id': ['id_0', 'id_1', 'id_2']})

b = pd.DataFrame({
          'id': ['id_0', 'id_1', 'id_3'], 
          'name': ['a', 'b', 'c']})

ab = pd.merge(a, b, on='id', how='inner')
>>>ab
	id	name
0	id_0	a
1	id_1	b

ab = pd.merge(a, b, on='id', how='outer')
>>>ab
	id	name
0	id_0	a
1	id_1	b
2	id_2	NaN
3	id_3	c

ab = pd.merge(a, b, on='id', how='right')
>>>ab
	id	name
0	id_0	a
1	id_1	b
2	id_3	c

また、自分自身をmergeすることもできます。
以下の例では、groupカラムを元にマージすることで、同じgroup内で総当たりのような行を増やしています。

df = pd.DataFrame({
          'group': [0, 0, 1], 
          'item': [0, 1, 0]})
df = df.merge(df,on='group') # 一つだけ指定

>>>df 
   group  item_x  item_y
0        0      0      0
1        0      0      1
2        0      1      0
3        0      1      1
4        1      0      0

isin

df_top = df.loc[df['country'].isin(top10)]

df_bottom = df.loc[~df['country'].isin(top10)]

sort_values

# 昇順
df_s = df.sort_values('state')
# 降順
df_s = df.sort_values('state', ascending=False)

欠損値確認

print(df.isnull().sum())

reset_index(リセット)

df = df.reset_index(drop=True)

# インデックスを残したかったら
df = df.reset_index()

シャッフル

df = df.sample(frac=1, random_state=0)

ラベル付け

df.loc[df['idx'].isin(idx_list), 'label'] = 1
df.loc[~df['idx'].isin(idx_list), 'label'] = 0

重複確認、重複削除

# 重複確認
df[df.duplicated(subset='text')]

# 重複削除
df = df.drop_duplicates(subset='text')

## 重複削除、複数指定すると、指定したカラムすべてが重複していたら削除
df = df.drop_duplicates(['group', 'item'])

値の割り当て

アクションごとにウェイトを割り当てるときなどに使えます。

action_weight = {0:1, 1:7, 2:3}
df = pd.DataFrame({
          'group': [0, 0, 0, 1],
          'action': [0, 0, 1, 2]})
df['wgt'] = df.action.map(action_weight) # weightの割り当て

>>>df
   group  action  wgt
0        0       0    1
1        0       0    1
2        0       1    7
3        1       2    3

二つの列を比較して、True/Falseの新しい列を生成

df = pd.DataFrame({
          'col1': [0, 0, 0], 
          'col2': [0, 0, 1],})

>>> df['predict'] = (df['col1'] == df['col2'])
>>> df['predict']
0     True
1     True
2    False

# 1/0に変換
>>> df['predict'] = df['predict'].astype(int)
0    1
1    1
2    0

参考:

ps://hack-le.com/pandas-2-true-false-10/

How can I map True/False to 1/0 in a Pandas DataFrame?
I have a column in python pandas DataFrame that has boolean True/False values, but for further calculations I need 1/0 representation. Is there a quick pandas/n...
タイトルとURLをコピーしました