見出し画像

【Python】Pythonを使って大容量CSVファイルからデータを抽出する方法

はじめに

こんにちは、CREFILの濱本です。
前回は、MacでPythonを使用する方法についてお話しましたので、今回は、Pythonを使って大容量CSVファイルからデータを抽出するためにどんなコマンドを使ったかを紹介していきます。

Pythonをどのような作業に使用したか

日次の売上データに対して、大きくは以下の作業を行いました。
 ・CSVファイルを一定容量ごとに分割
 ・条件に一致するデータのみを抽出
 ・複数のCSVファイルを1つのデータに結合し、ファイル出力
 ・データ加工
 ・日次データを週ごとに集計し週次データを作成
 ・カラム追加(条件にあうテキストや数字、日付などのデータを入力)

事前作業

事前にライブラリとして「pandas」と「datetime」をインポートしてあります。なおpandasを ”pd”という名前で扱えるようにしています。インポート方法はMacでPythonを使ってみよう を参照ください。

ファイル分割

対象のファイルを読み込んで、2,000,000行ごとに分割して、ファイルに出力します。

i = 0
for df in pd.read_csv('/Users/XXXX/Documents/BIsample/T_SUPPORT_SALES_DAILY_2019-2020.csv',encoding='shiftJIS',low_memory=False,chunksize=20000000):
	i = i + 1
	df.to_csv('DAILY_2019-2020_' + str(i) + '.csv',header=True,index=False)

※試したファイルの場合は2,000,000行ごとにファイル分割(chunksize=20000000 )をしたところ、1ファイルのサイズがおおよそ50GBくらいになりました。

特定カラムで文字列に一致するレコードのみを抽出

各ファイルごとに、カラム名「CUSTOMER_CODE」において、コードがA0001、A0002、A0003、A0004、A0005に一致するレコードのみを抽出します。

# 読み込みファイルにheaderがある場合
 # ファイルの読み込み
 df = pd.read_csv('/Users/XXXX/Documents/BIsample/DAILY_2019-2020_1.csv',encoding='shiftJIS',low_memory=False)

 # フィルタリング
 filtering = df['CUSTOMER_CODE'].str.contains('A0001|A0002|A0003|A0004|A0005' )



# 読み込みファイルにheaderがない場合
 # ファイルの読み込み
 df = pd.read_csv('/Users/XXXX/Documents/BIsample/DAILY_2019-2020_1.csv',encoding='shiftJIS',low_memory=False,header=None)

 # フィルタリング ※headerがない場合は、列番号で指定する
 filtering = df[0].str.contains('A0001|A0002|A0003|A0004|A0005' )




# 以下は共通作業
 # 表示(フィルタリング条件に合うものがあれば表示される)
 df[filtering]

 # 表示結果があれば、CSV出力
 df[filtering].to_csv('FIL_DAILY_2019-2020_1.csv',header=True,index=False)

ファイル結合

上記作業を分割したファイル分繰り返し、データを結合し1つのCSVファイルにまとめます。

# 初回のファイル結合
 # 結合元ファイル指定(ベースファイル)
 df1 = pd.read_csv('/Users/XXXX/Documents/BIsample/FIL_DAILY_2019-2020_1.csv',encoding='shiftJIS',low_memory=False)

 # 結合相手指定
 df2 = pd.read_csv('/Users/XXXX/Documents/BIsample/FIL_DAILY_2019-2020_2.csv',encoding='shiftJIS',low_memory=False)

 # ファイル結合
 df_concat=pd.concat([df1,df2],axis=0)



# 2回目以降
 # 結合元ファイル指定(ベースファイル)
 df1 = df_concat

 # 結合相手指定
 df2 = pd.read_csv('/Users/XXXX/Documents/BIsample/XXX.csv',encoding='shiftJIS',low_memory=False)

 # ファイル結合
 df_concat=pd.concat([df1,df2],axis=0)



# すべての結合が終わったら
 # 結合データをCSV出力
 df_concat.to_csv('FIL_DAILY_2019-2023.csv',header=True,index=False)

日次データを集計して週次データを作成

年、週、店舗コード、商品コードが一致するデータの1週間の売上金額合計を持つ週次データを作成します。(※週集計は月曜日はじまりで計算)

1. CSVファイルの読み込み

df = pd.read_csv('/Users/XXXX/Documents/BIsample/FIL_DAILY_2019-2023.csv',encoding='shiftJIS',low_memory=False)

2. 新カラムの作成

# 新カラム 'newDate' (データ型変換)、'weekYear’(年)、'weekWeek’(週番号)、('weekNum’曜日) の作成および値設定

def addWeekNumber(row):
	row['newDate'] = pd.to_datetime(row['DELIVERED_DATE'],format='%y-%m-%d')
	row['weekYear'] = row['newDate'].isocalendar()[0]
	row['weekWeek'] = row['newDate'].isocalendar()[1]
	row['weekNum'] = row['newDate'].isocalendar()[2]
	return row
df = df.apply(addWeekNumber, axis=1)

3. 重複排除

ここでは、日次データを週次データにするため、
'weekYear’(年)、'weekWeek’(週番号)、'CUSTOMER_CODE_STORE’(店舗コード)、['PRODUCT_CODE’(商品コード)が一致するデータを重複排除したdfを作ります。

# 重複チェックキーを作成

def addDuplicationKey(row):
	row['duplicationKey'] =  str(row['weekYear']) + '' + str(row['weekWeek']) + '' + str(row['CUSTOMER_CODE_STORE']) + '_' + str(row['PRODUCT_CODE'])
	return row

df = df.apply(addDuplicationKey, axis=1)



# 重複排除の実行

dfDrop = df.drop_duplicates(subset = 'duplicationKey')

4. 売上金額の1週間ごとの合計を計算

# 売上金額の合計

salesAmout = df[['duplicationKey','SALES_AMOUNT']].groupby('duplicationKey').sum()

5. 週次データを代入

def addSumAnswer(row):
        a = salesAmout.loc[[row['duplicationKey']], 'SALES_AMOUNT'][0]
        row['SALES_AMOUNT'] = a
        return row
answer = answer.apply(addSumAnswer, axis=1)

6. 各週の月曜日の日付を代入

# relativedeltaのインポート

from dateutil.relativedelta import relativedelta



# 各週の月曜日の日付に変更

def setMondayDate(row):
	if row['weekNum'] > 1:
		a = -(row['weekNum'] -1)
		row['newDate']  = row['newDate'] + relativedelta(days=a)
	return row
dfweek = dfweek.apply(setMondayDate, axis=1)

7. CSV出力

dfweek.to_csv('WEEKLY_2019-2023.csv',header=True,index=False)

おわりに

実際に使用したコマンドの一部を紹介いたしました。
普段Excelで関数やピボットテーブルなどを活用してデータの抽出などをしている方も、大きなサイズのデータだとうまくできないこともあると思うので、そういったときはPythonを使ってみてはいかがでしょうか。

最後まで読んでいただき、ありがとうございました。
「スキ」や「フォロー」頂けると励みになります!


この記事が参加している募集

#企業のnote

with note pro

12,555件