PythonはPandasを使って大量のデータを処理する

2804 ワード

最近1つの需要を受け取ったのは100 G近くのCSVデータ(複数のディレクトリの複数のファイル、単一のファイルは最大1 Gで、各ディレクトリの下で同じ種類の目的のデータで、クラスのデータは並べ替えて処理する必要があります)をMysqlに導入します
環境:デスクトップノートパソコン、i 5+8 G(約2 G使用可能メモリ)+128 GSSD+1 T+Win 10
実現過程に流水勘定を記入する
最初はPHPかpythonで、1行1行読み出してから書き込み、計算するのに時間がかかりすぎて、最終的にpython+pandasスキームを選びました
その中で出会った穴:
1、dtype
直接pandas.read_csvの时に大きいファイルのメモリのオーバーフローのプログラムが终わることに出会って、成分を変えて読み取ります解决します
import pandas as pd

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

に届く
C:/path/to/python.exe E:/data/pd.py sys:1: DtypeWarning: Columns (3) have mixed types. Specify dtype option on import or set low_memory=False.
解決:
1、ロード前にdtypeまたは2を設定し、low_を設定するmemory=False
df = pd.read_csv('path/to/file',dtype={"cat_id":int, "cat_name":object})

しかしcat_id列はすべてintタイプでなければなりません
2つ目の方法を選びました
df = pd.read_csv('path/to/file',low_memory=False)

2、メモリオーバーフロー
コンピュータの使用可能なメモリが少ないため、実行中にメモリオーバーフローが発生します.
寝る前にプログラムがうまくいっていると思って、寝床にもぐり込んでぐっすり寝ていたら、朝起きたら横になったかと思うと
そこでスライス読み取りに変更しました
# -*- coding: utf-8 -*-

#       
import pandas as pd
import os
from sqlalchemy import create_engine

#         ,  pymysql  
engine = create_engine('mysql+pymysql://user:password@server:port/db_name?charset=utf8')
#       
reader = pd.read_csv('path/to/file',low_memory=False, chunksize=1000000)
d = 'path'
#    
for dir in os.listdir(d):
    dd = []
    #    
    for file in os.listdir(d.'/'.dir):
        for df in reader:
            dd.append(df)
    df = pd.concat(dd, ignore_index=True)
    #       
    #      
    df.to_sql('table_name', engine, index= True, if_exists='append')

そしてデータベースを書くときにオーバーフローしました
# -*- coding: utf-8 -*-

#       
import pandas as pd
import os
from sqlalchemy import create_engine

#         ,  pymysql  
engine = create_engine('mysql+pymysql://user:password@server:port/db_name?charset=utf8')
#       
reader = pd.read_csv('path/to/file',low_memory=False, chunksize=1000000)
d = 'path'
#    
for dir in os.listdir(d):
    dd = []
    #    
    for file in os.listdir(d.'/'.dir):
        for df in reader:
            dd.append(df)
    df = pd.concat(dd, ignore_index=True)
    #       
    #      
    i = len(df.index)
    size = 1000000
    while i > 0 :
        start = i - size
        if start < 0:
            start = 0
        dfn = df.loc[start:i]
        i=i-size
        dfn.to_sql('table_name', engine, index= False, if_exists='append')
    # df.to_sql('table_name', engine, index= True, if_exists='append')

大功を成し遂げる
表の構造はデータを挿入する前に準備して、挿入後のデータが大きすぎて修正するのに時間がかかりすぎることを防止します