Python使用Pandas处理大量数据

最近接到一个需求是把近100G的CSV数据(多个目录的多个文件,单文件最大1G,每个目录下是同一类目的数据,类目数据需要做排重处理)导入Mysql

环境:桌面笔记本电脑,i5+8G(约2G可用内存)+128GSSD+1T+Win10

实现过程记个流水账

最开始是想用PHP或python,一行一行读取,然后再写入,计算了一下需要时间太长了,最终选择了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、内存溢出

由于电脑可用内存比较少,运行过程中出现内存溢出

本来以为睡觉前以为程序跑得很好,于是钻被窝睡个安稳觉,可是早上起来发现刚躺下就crash掉了

于是改成了分片读取

# -*- 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')

大功告成

表结构在插入数据前准备好,防止插入后数据太大修改耗时过长

 

你可能感兴趣的:(Python,Pandas)