【更新型エントリ】pandasメモ

2021年9月22日水曜日

t f B! P L

インポート

#ライブラリのインポート
import pandas as pd

データフレームの作成方法いろいろ

#データフレームの作成
#手動でデータフレームを作成
df = pd.DataFrame({'Age':[21,22,23,24],
                   #'表の項目':[表の要素]
                   'Gender':['M','M','F','F'],
                   'Height':[160,170,190,175], 
                   'Weight': [45,60,76,70]})

#csvファイルの読み込み gzipでもいける。
df = pd.read_csv('./input/csv/sales_train_validation.csv.gz')

#pickleでも読める
df = pd.read_pickle('input/pickle/df_id_sales_with_calender_price.pickle.gz')

#pickleで書き出す
import pickle
import gzip
df_dump = pickle.dumps(df)
with gzip.open('./df.pickle.gz', mode='wb') as fp:
    fp.write(df_dump)
または
with gzip.open('input/pickle/df_sales_with_calender_price_days.pickle.gz', mode='wb') as fp:
    fp.write(pickle.dumps(df_sales))

#メモリに載りきらない場合
def preprocess(x):
    # 不要な行, 列のフィルタなど、データサイズを削減する処理
    return x

reader = pd.read_csv(fname, skiprows=[0, 1], chunksize=50)
df = pd.concat((preprocess(r) for r in reader), ignore_index=True)

#型の推論を一部のデータでやると読み込み時のメモリ使用量削減
df = pd.read_csv("sample1.csv",low_memory=True) 

#読み込むカラム指定
df = pd.read_csv('./data.csv', usecols=['columnA', 'columnB', 'columnC'])

#型指定
data = pd.read_csv('./data.csv',
            dtype={'id': np.int64,
                   'url': np.object,
                   'region': np.object,
                   'region_url': np.object,
                   'price': np.int64,
                   'year': np.float16})

情報表示

#dfの概要を出す
df.info()

カラム名、インデックス名を取り出し利用する

#全ての列の名前を出す
df.columns
for column in df.columns:
	(処理を記述)

#全てのindexを出す
df.index

カラム名を変更する

#特定の列と行だけ名前を変更する
df = df.rename(columns={'column':'renamed_columns'}, index={'index':'renamed_index'})

カラムを削除する

#列を削除
df = df.drop(columns='column_name') #columnsというパラメータで指定
df = df.drop(["column_name1", "column_name2"], axis=1)

df.loc 特定行・列を取り出す

#インデックスと列名を同時に指定して参照する
df.loc['index_name','column_name']

#複数のデータを取り出す
#全ての行のcolumn1とcolumn2を取り出す
df.loc[:, ["column1","column2"]]

#条件を満たすデータを取り出す
# Ageが20以上の行を取り出す。
df[df['Age']>=20]

# df['Age']>=20 を満たす行を取り出し、列は["Height", "Weight"]だけ表示する
df.loc[df['Age']>=20, ["Height", "Weight"]]

並べ替え

#データを並び替える
#ascendingは上昇の意味
df.sort_values('Age', ascending=True)

集計

# 特定列に存在するユニークな値とその出現回数を求める
df["column_name"].value_counts()

# 性別毎に集計をして、各列の平均を求める
df.groupby("Sex").mean()

#基本統計量を出す
#最大値
print(df.loc[:,'Weight'].max())
#中央値
print(df.loc[:,'Weight'].median())
#最小値
print(df.loc[:,'Weight'].min())

#基本統計量をまとめて出す
df.describe()

欠損値の処理

##  欠損値の有無を出力
df_titanic.isnull().sum()

#dropna関数は欠損値の行を削除する
df_dropna = df.dropna()

#fillna関数を用いて平均値で欠損値を置き換え
df_fillna = df.fillna(df.mean())

結合

#新しい行と既存の表dfを結合する
#axisは結合の方向,0で縦方向に結合,1で横方向に結合
new_df=pd.concat([df,new_row],axis=0)

横持ち→縦持ち変換

df_melt = pd.melt(df, id_vars=['id', 'item_id', 'dept_id', 'cat_id', 'store_id', 'state_id']) 

メモリ使用量削減関数

def reduce_mem_usage(df, verbose=True):
    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
    start_mem = df.memory_usage().sum() / 1024**2    
    for col in df.columns:
        col_type = df[col].dtypes
        if col_type in numerics:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)    
    end_mem = df.memory_usage().sum() / 1024**2
    if verbose: print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(end_mem, 100 * (start_mem - end_mem) / start_mem))
    return df

df = reduce_mem_usage(df)

表のjoin

df_sales_cal = pd.merge(df_analysis, df_calender, on='d', how='inner')
df_sales = pd.merge(df_sales, df_itemstart, on=['item_id', 'store_id'], how='left')

特定カラムに関数適用

def str_to_datetime(t):
    return datetime.datetime.strptime(t, '%Y-%m-%d')

df_sales['date'] = df_sales['date'].apply(str_to_datetime)

インデックスリセット

df_sales = df_sales[(df_sales['from_itemstart'] > 0)].reset_index(drop=True) #drop=Trueとしないと元のインデックスがカラムに追加される

時系列データ処理

def prep_selling_prices(df):
    gr = df.groupby(["store_id", "item_id"])["sell_price"]
    df["sell_price_rel_diff"] = gr.pct_change()
    df["sell_price_roll_sd7"] = gr.transform(lambda x: x.rolling(7).std())
    df["sell_price_cumrel"] = (gr.shift(0) - gr.cummin()) / (1 + gr.cummax() - gr.cummin())
    df = reduce_mem_usage(df)
    return df

numpy変換

# Input dict for training with a dense array and separate inputs for each embedding input
def make_X(df):
    X = {"dense1": df[dense_cols].to_numpy()}
    for i, v in enumerate(cat_cols):
        X[v] = df[[v]].to_numpy()
    return X

カテゴリ変数をダミー変数に変換

pd.get_dummies(df, drop_first=True, columns=['sex', 'rank'])

重複行削除

df.drop_duplicates()

セル内改行を削除

df_item = pd.read_excel('商品マスタ.xlsx').replace('\n', '', regex=True)

あるカラムに/区切り複数要素を持っているとき、行を分ける

df_tmp = pd.concat([pd.Series(row['A'], row['B'].split('/'))              
                    for _, row in df.iterrows()]).reset_index()
df_tmp = df_tmp.rename(columns={'index':'B', 0:'A'})
df_tmp

datetime型に変換して月別集計

transaction['payment_date'] = pd.to_datetime(transaction['payment_date'])
transaction['payment_month'] = transaction['payment_date'].dt.strftime('%Y%m')
transaction.groupby('payment_month').sum()['price']

表記の揺れ補正(大文字に揃えて空白削除)

df["name"] = df["name"].str.upper()
df["name"] = df["name"].str.replace(" ", "")
df["name"] = df["name"].str.replace(" ", "")
df.sort_values(by=["item_name"], ascending=True)

欠損値補完

flg_is_null = uriage_data["item_price"].isnull()
for trg in list(uriage_data.loc[flg_is_null, "item_name"].unique()):
    price = uriage_data.loc[(~flg_is_null) & (uriage_data["item_name"] == trg), "item_price"].max()
    uriage_data["item_price"].loc[(flg_is_null) & (uriage_data["item_name"]==trg)] = price
uriage_data.head()

日付の表記ゆれ補正

flg_is_serial = kokyaku_data["登録日"].astype("str").str.isdigit()
flg_is_serial.sum()
fromSerial = pd.to_timedelta(kokyaku_data.loc[flg_is_serial, "登録日"].astype("float"), unit="D") + pd.to_datetime("1900/01/01")
fromSerial
fromString = pd.to_datetime(kokyaku_data.loc[~flg_is_serial, "登録日"])
fromString
kokyaku_data["登録日"] = pd.concat([fromSerial, fromString])
kokyaku_data
kokyaku_data["登録年月"] = kokyaku_data["登録日"].dt.strftime("%Y%m")
rslt = kokyaku_data.groupby("登録年月").count()["顧客名"]
print(rslt)
print(len(kokyaku_data))

title

xxx

title

xxx

title

xxx

このブログを検索

ブログ アーカイブ

AD

自己紹介

自分の写真
機械学習による売上予測モデル構築や商品ポートフォリオ最適化に取り組むAI屋です。E資格・G検定保有。LINEスタンプ販売やYoutubeもやってます。

QooQ