記錄一次讀取1600萬 行 X 41列的csv文件。
目標 /環境
文件數據爲測試模擬數據,數據大小 9.8G,目標爲讀取數據,並且寫入mysql。
目標文件
運行環境:
python3.6 (64位),pandas,pymysql。
思路
採用pandas內置read_csv方法,分塊讀取文件,開4個進程寫入mysql。
遇到的坑有,memoryerror,這裏需要強調!!! 必須把寫入過的數據del掉,然後調用gc.collect() 釋放內存,否則,一直會出現memoryerror,因爲python的垃圾回收機制必須試函數執行完才釋放,按照這個思路,不等數據讀取完,內存就炸了。
下面上代碼。
代碼
import pandas as pd
from sqlalchemy import create_engine
from multiprocessing import Pool
import gc
def gets():
"""分塊讀取文件,其實1,000,000行據說速度最佳。"""
df1 = pd.read_csv(r'C:\\Users\\zq\\Desktop\\Project\\demo_python\\測試2.csv', low_memory=False, chunksize=500000)
return df1
def to_sqls(df, table):
"""寫入mysql"""
engine = create_engine('mysql+pymysql://root:[email protected]:3306/demo',
max_overflow=0, pool_size=5,
pool_timeout=30, pool_recycle=-1)
con = engine.connect()
df.to_sql(table, con=con, if_exists='append')
del df#刪除掉變量,釋放內存。
gc.collect()
def get_times():
p = Pool(4)
df = gets()
for df1 in df:
print(df1.shape[0])
for i in range(0, df1.shape[0] + 1, int((df1.shape[0] + 1) / 4)):
if (i + int((df1.shape[0] + 1) / 4)) < (df1.shape[0] + 1):
p.apply_async(to_sqls, args=(df1.iloc[i:i + int((df1.shape[0] + 1) / 4), :], 'ce'))
else:#超出文件範圍
p.apply_async(to_sqls, args=(df1.iloc[i:df1.shape[0] + 1, :], 'ce'))
p.close()
p.join()
if __name__ == '__main__':
import time
t1 = time.time()
get_times()
t2 = time.time() - t1
print('%s s' % t2)
結果。
實際測試時間爲:1161.214187860489 s完成整個程序。(包含讀取 和寫入)
數據庫結果如下。
本次記錄到此。如果後期發現更快的方法,將繼續分享。