原创 Zero 爱读书的小狼 2024-04-27 15:30
原文首发于微信公众号:Python应用:基于CSV文件的建表和数据清洗
背景:
因为工作原因,要从某个平台上导出数据在本地进行分析和日常备份。该平台只提供了CSV格式文件导出,之前数据量小的时候,拿excel尚可对付。后来数据量变大,excel加载都比较困难,动不动就崩,且excel对长数字不友好,不是被转换成科学记数法,就是后几位变成0,每次碰到这样的问题还得单个处理,很是耗时。当然excel在数据综合处理方面较弱也是一个重要原因。
为方便后续工作,打算建立本地数据库。数据库我选择了DM8,它在功能性、友好性、安全性、拓展性上表现均不俗,有人说它是Oracel的国产化替代产品,就用户体验来说,确是如此。
闲话少扯,上代码:
#!python3
# By Zero, 2024-04-25
# 环境:Win7, p38
import os
import pandas as pd
# 定义文件路径和文件名处理函数
def get_file_paths(base_path, file_name):
print(f"获取文件路径: {base_path}, {file_name}")
fname = os.path.join(base_path, file_name)
ct_file = os.path.join(base_path, 'ct_' + os.path.splitext(file_name)[0].upper() + '.sql')
new_file = os.path.join(base_path, 'new_' + os.path.splitext(file_name)[0] + '.csv')
print(f"文件路径: {fname}, {ct_file}, {new_file}")
return fname, ct_file, new_file
# 定义读取和清洗DataFrame的函数
def clean_dataframe(fname):
print(f"开始读取文件: {fname}")
try:
df = pd.read_csv(fname, encoding='utf-8', low_memory=False)
print(f"文件读取成功")
except Exception as e:
print(f"文件读取失败: {e}")
return None
print(f"开始清洗数据")
df = df.astype(str)
df = df.replace({'\t': '$', '\n': '*', 'nan': ''}, regex=True)
df = df.apply(lambda col: col.str.replace(r'\.0$', '', regex=True) if col.dtypes == object else col)
print(f"数据清洗完成")
return df
# 定义计算列最大长度并生成SQL建表脚本的函数
def generate_sql_script(df, ct_file):
if df is None:
print(f"DataFrame为空,无法生成SQL脚本")
return None
print(f"开始生成SQL建表脚本: {ct_file}")
max_lengths = df.apply(lambda col: col.str.len().max())
#列长列表
LL = [1 if x == 0 else x for x in max_lengths]
#列名列表
LC = list(df.columns)
try:
with open(ct_file, 'w', encoding='utf-8') as f:
f.write('CREATE TABLE "{tname}" (\n'.format(tname=os.path.splitext(ct_file)[0].split('_')[1].upper()))
for i in range(0, len(LL)):
f.write(f' "{LC[i]}" VARCHAR2({LL[i]})')
if i < len(LL) - 1:
f.write(',\n')
f.write(');\n')
print(f"SQL建表脚本生成成功: {ct_file}")
except Exception as e:
print(f"SQL建表脚本生成失败: {e}")
return None
return ct_file
# 定义保存清洗后DataFrame为CSV文件的函数
def save_cleaned_dataframe(df, new_file):
if df is None:
print(f"DataFrame为空,无法保存为CSV文件")
return None
print(f"开始保存清洗后的数据为CSV文件: {new_file}")
try:
df.to_csv(new_file, encoding='utf-8', index=False)
print(f"CSV文件保存成功: {new_file}")
except Exception as e:
print(f"CSV文件保存失败: {e}")
return None
return new_file
# 主程序
def main():
# 定义路径和文件名
base_path = r'D:\Download' # 请替换为您的文件路径
file_name = r'_601.csv' # 请替换为您的文件名
# 获取文件路径
fname, ct_file, new_file = get_file_paths(base_path, file_name)
# 读取和清洗DataFrame
df = clean_dataframe(fname)
if df is None:
print("无法读取或清洗数据,程序结束。")
return
# 生成SQL建表脚本
sql_script_file = generate_sql_script(df, ct_file)
if sql_script_file is None:
print("无法生成SQL建表脚本,程序结束。")
return
# 保存清洗后DataFrame为CSV文件
save_cleaned_dataframe(df, new_file)
# 发送操作完成通知
print("所有操作完成。")
# 如果这个脚本是作为主程序运行(而不是被导入),则执行main函数
if __name__ == "__main__":
main()
题外话:码字时请教过Ai几个问题,不得不说,百度还是有了些进步,Ai的回答也是比较准确,希望保持并继续努力吧。