pyhton3 execl 数据插入追加

本文介绍了一个Python脚本,该脚本利用xlrd、xlwt和pymssql库实现从SQL Server数据库中读取数据并批量写入到Excel文件中,同时支持从Excel读取数据追加到同一工作簿。脚本展示了如何使用正则表达式处理HTTP请求返回的数据,以及如何通过SQL查询获取商品信息。
# coding=UTF-8
import xlrd
import xlwt
from xlutils.copy import copy
import requests,re,time
import pymssql

def con_sql(ssql):
    #连接SQL
    conn = pymssql.connect(host='xxxxx',
                           user='xxxxxxxxx',
                           password='xxxxxx',
                           database='xxxxxxxxxxx',
                           charset='utf8')

    #查看连接是否成功
    cursor = conn.cursor()
    sql = ssql
    cursor.execute(sql)
    #用一个rs变量获取数据
    rs = cursor.fetchall()
    conn.close()
    return rs


def write_excel_xls(path, sheet_name, value):
    index = len(value)  # 获取需要写入数据的行数
    workbook = xlwt.Workbook()  # 新建一个工作簿
    sheet = workbook.add_sheet(sheet_name)  # 在工作簿中新建一个表格
    for i in range(0, index):
        for j in range(0, len(value[i])):
            sheet.write(i, j, value[i][j])  # 像表格中写入数据(对应的行和列)
    workbook.save(path)  # 保存工作簿
    print("xls格式表格写入数据成功!")


def write_excel_xls_append(path, value):
    index = len(value)  # 获取需要写入数据的行数
    workbook = xlrd.open_workbook(path)  # 打开工作簿
    sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
    worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
    rows_old = worksheet.nrows  # 获取表格中已存在的数据的行数
    new_workbook = copy(workbook)  # 将xlrd对象拷贝转化为xlwt对象
    new_worksheet = new_workbook.get_sheet(0)  # 获取转化后工作簿中的第一个表格
    for i in range(0, index):
        for j in range(0, len(value[i])):
            new_worksheet.write(i + rows_old, j, value[i][j])  # 追加写入数据,注意是从i+rows_old行开始写入
    new_workbook.save(path)  # 保存工作簿
    print("xls格式表格【追加】写入数据成功!")


def read_excel_xls(path):
    workbook = xlrd.open_workbook(path)  # 打开工作簿
    sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
    worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
    for i in range(0, worksheet.nrows):
        for j in range(0, worksheet.ncols):
            print(worksheet.cell_value(i, j), "\t", end="")  # 逐行逐列读取数据
        print()




#########################################################################################
otherStyleTime = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
book_name_xls = f'D:\\关键词搜索工作簿_{str(otherStyleTime)}.xls'
sheet_name_xls = '关键词搜索'
value_title = [["搜索词", "分词结果","推荐词", "搜索结果", "商品名称", "所属一级分类","所属二级分类","所属三级分类","所属品牌"] ]
write_excel_xls(book_name_xls, sheet_name_xls, value_title)
ser='D:\\se.txt'
with open(ser,'r')as e:
    for se in e.readlines():
        print(se)
        r1 = requests.get(f'http://api.xxxxxxxxxxxxxxxx/directsearch/search?source=all50keyword&keyword={se}&showFlag=1,'
             '3&selectType=2&promotionChannelType=2&isExcludeJiCai=1&appId=110001&platform=pc&ip=127.0.0.1&sortBy=vcdesc&page=1&pageSize=10')
        pat = re.compile(r'Id":(.*?),', re.S)
        result = pat.findall(r1.text)
        pat2 = re.compile(r'tokens":"(.*?)"', re.S)
        pat3 = re.compile(r'effectiveTokens":"(.*?)"', re.S)
        result2 = pat2.findall(r1.text)
        result3 = pat3.findall(r1.text)
        #获取商品skuid
        j=[]
        for i in result:
            #i= str(i)
            i=re.findall(r"\d{9}",i)
            j.append(i)
            for z in j:
                if z==[]:
                    j.remove(z)
        #循环SKUID写EXECL
        for i in j:
            # 写入EXECL
            sql=f"""SELECT  p.Name ,
                        p.Brand ,
                        CategoryName1 ,
                        CategoryName2 ,
                        CategoryName3
                FROM    dbo.t_Product_Product p
                        INNER JOIN ( SELECT c.Id ,
                                            CategoryName1 = a.Name ,
                                            CategoryName2 = b.Name ,
                                            CategoryName3 = c.Name
                                     FROM   t_Product_Category a
                                            INNER JOIN t_Product_Category b ON a.Id = b.ParentId
                                                                              AND a.Mark > 0
                                                                              AND b.Mark > 0
                                            INNER JOIN t_Product_Category c ON b.Id = c.ParentId
                                                                              AND c.Mark > 0
                                   ) t ON p.CategoryId3 = t.Id
                WHERE   p.Mark > 0 AND p.Id={i[0]}"""
            res_sql = con_sql(sql)
            print(res_sql)
            #元组取值
            for o in res_sql:
                print(o)
            #调用方法执行
            value1 = [[se, result2,result3, str(i[0]),o[0],o[2],o[3],o[4],o[1]]]
            write_excel_xls_append(book_name_xls, value1)
            read_excel_xls(book_name_xls)










<think>我们正在讨论如何使用Python(特别是Pandas库)来清洗Excel数据,特别是填充空白单元格。根据引用[4]中提到的数据清洗,以及引用[3]中提到的Excel处理缺失值的方法(包括填充),我们需要用Python实现类似的功能。 在Pandas中,处理缺失值(NaN或None)的方法有很多,特别是填充空白单元格。以下是一些常用的方法: 1. 使用固定值填充:用指定的值(如0、平均值、中位数等)填充缺失值。 2. 前向填充(ffill)或后向填充(bfill):使用前面的值或后面的值填充。 3. 使用插值方法:例如线性插值等。 引用[3]中提到了Excel的填充方法(如使用上方/下方单元格填充,或使用平均值等)。在Pandas中,对应的方法为: - `fillna()`: 用于填充缺失值的主要方法。 具体步骤: 1. 读取Excel文件 2. 检查缺失值(空白单元格在Pandas中通常被读为NaN) 3. 选择填充策略并填充 下面我将详细说明。 ### 步骤1: 读取Excel文件 ```python import pandas as pd # 读取Excel文件 df = pd.read_excel(&#39;your_file.xlsx&#39;) ``` ### 步骤2: 检查缺失值 ```python # 查看每列缺失值的数量 print(df.isnull().sum()) # 或者查看整个数据框的缺失值情况 print(df.isnull()) ``` ### 步骤3: 填充缺失值 #### 方法1: 用固定值填充 ```python # 用0填充所有缺失值 df_filled = df.fillna(0) # 用每列的平均值填充 df_filled = df.fillna(df.mean()) # 对于数值列 # 或者针对某一列 df[&#39;列名&#39;] = df[&#39;列名&#39;].fillna(df[&#39;列名&#39;].mean()) # 用每列的中位数填充 df_filled = df.fillna(df.median()) # 用指定字符串填充(针对非数值列) df[&#39;列名&#39;] = df[&#39;列名&#39;].fillna(&#39;未知&#39;) ``` #### 方法2: 前向填充或后向填充 ```python # 前向填充:用前面的值填充后面的缺失值 df_filled = df.fillna(method=&#39;ffill&#39;) # 也可以指定axis(默认是0,沿行向下填充) # 后向填充:用后面的值填充前面的缺失值 df_filled = df.fillna(method=&#39;bfill&#39;) ``` #### 方法3: 插值 Pandas提供了插值方法,可以按一定规则插值(如线性插值、时间序列插值等): ```python # 线性插值(默认按列插值,沿index方向) df_interpolated = df.interpolate() # 如果数据是时间序列,可以使用时间插值 # 假设index是时间,可以设置method=&#39;time&#39; # df_interpolated = df.interpolate(method=&#39;time&#39;) ``` ### 示例:综合应用 假设我们有一个包含学生信息的Excel表格,其中“年龄”列有缺失,我们想用平均年龄填充;“性别”列有缺失,我们想用“未知”填充;而“成绩”列我们想用前向填充。 ```python # 读取数据 df = pd.read_excel(&#39;students.xlsx&#39;) # 分别处理不同列 df[&#39;年龄&#39;] = df[&#39;年龄&#39;].fillna(df[&#39;年龄&#39;].mean()) df[&#39;性别&#39;] = df[&#39;性别&#39;].fillna(&#39;未知&#39;) df[&#39;成绩&#39;] = df[&#39;成绩&#39;].fillna(method=&#39;ffill&#39;) # 或者一次性对不同列用不同方法填充 # 使用字典传递给fillna df = df.fillna({ &#39;年龄&#39;: df[&#39;年龄&#39;].mean(), &#39;性别&#39;: &#39;未知&#39;, &#39;成绩&#39;: method=&#39;ffill&#39; # 注意:这里不能直接这样写,因为fillna的字典值只能是标量或指定方法需要单独处理 }) # 但是,fillna的字典参数不支持方法,所以对于需要不同填充方法的列,可以分别处理 ``` 注意:`fillna`的字典参数只能接受标量值,不能接受方法(如&#39;ffill&#39;)。因此,对于需要不同填充方法的列,最好分别处理。 ### 注意事项 1. 在填充之前,需要根据数据特点选择合适的方法。例如,时间序列数据常用前向填充或插值。 2. 填充可能会引入偏差,特别是用统计值(如均值)填充时,需谨慎。 3. 对于分类数据,使用众数填充可能更合适。 ### 可视化缺失值(可选) 在清洗前,可以使用可视化工具查看缺失值分布,例如使用`missingno`库: ```python import missingno as msno msno.matrix(df) plt.show() ``` ### 保存清洗后的数据 ```python df.to_excel(&#39;cleaned_students.xlsx&#39;, index=False) ``` ### 引用说明 以上方法参考了Pandas官方文档以及实际数据处理中的常用实践[^2][^3][^4]。 §§相关问题§§ 1. 如何识别Excel数据中的异常值并用Python处理? 2. 如何使用Python删除Excel中的重复数据3. 在Pandas中如何处理非标准缺失值(如"NA"、"?"等)? 4. 如何将清洗后的数据导出到Excel的不同工作表(Sheet)? </think># Python 实现 Excel 数据清洗:空白单元格填充方法 在 Excel 数据处理中,空白单元格是常见的数据质量问题。以下是使用 Python 进行 Excel 数据清洗时填充空白单元格的完整方案: ## 一、基础方法:Pandas 内置函数 ### 1. 固定值填充 ```python import pandas as pd # 读取 Excel 文件 df = pd.read_excel(&#39;data.xlsx&#39;) # 所有空白单元格填充为 0 df_filled = df.fillna(0) # 特定列填充指定值 df[&#39;销售额&#39;] = df[&#39;销售额&#39;].fillna(0) ``` ### 2. 向前/向后填充 ```python # 向前填充(使用上方单元格的值) df_ffill = df.fillna(method=&#39;ffill&#39;) # 向后填充(使用下方单元格的值) df_bfill = df.fillna(method=&#39;bfill&#39;) # 组合使用(先向前再向后填充) df_combined = df.fillna(method=&#39;ffill&#39;).fillna(method=&#39;bfill&#39;) ``` ### 3. 统计值填充 ```python # 均值填充(数值型列) df[&#39;价格&#39;] = df[&#39;价格&#39;].fillna(df[&#39;价格&#39;].mean()) # 中位数填充 df[&#39;年龄&#39;] = df[&#39;年龄&#39;].fillna(df[&#39;年龄&#39;].median()) # 众数填充(分类型数据) df[&#39;产品类别&#39;] = df[&#39;产品类别&#39;].fillna(df[&#39;产品类别&#39;].mode()[0]) ``` ## 二、高级填充策略 ### 1. 分组填充 ```python # 按部门分组后填充部门平均薪资 df[&#39;薪资&#39;] = df.groupby(&#39;部门&#39;)[&#39;薪资&#39;].transform( lambda x: x.fillna(x.mean()) ) ``` ### 2. 基于时间序列的填充 ```python # 时间序列插值填充(适合时间序列数据) df[&#39;温度&#39;] = df[&#39;温度&#39;].interpolate(method=&#39;time&#39;) ``` ### 3. 多列关联填充 ```python # 根据产品类别填充缺失价格 category_avg = df.groupby(&#39;产品类别&#39;)[&#39;价格&#39;].mean().to_dict() df[&#39;价格&#39;] = df.apply( lambda row: category_avg[row[&#39;产品类别&#39;]] if pd.isna(row[&#39;价格&#39;]) else row[&#39;价格&#39;], axis=1 ) ``` ## 三、完整数据清洗流程 ```python def clean_excel_data(file_path): # 1. 读取数据 df = pd.read_excel(file_path) # 2. 空白单元格诊断 print("缺失值统计:") print(df.isnull().sum()) # 3. 填充策略 # 数值列用中位数填充 num_cols = df.select_dtypes(include=&#39;number&#39;).columns for col in num_cols: df[col] = df[col].fillna(df[col].median()) # 分类列用众数填充 cat_cols = df.select_dtypes(include=&#39;object&#39;).columns for col in cat_cols: df[col] = df[col].fillna(df[col].mode()[0]) # 4. 时间序列特殊处理 if &#39;日期&#39; in df.columns: df[&#39;日期&#39;] = pd.to_datetime(df[&#39;日期&#39;]) df.sort_values(&#39;日期&#39;, inplace=True) df.interpolate(method=&#39;time&#39;, inplace=True) # 5. 保存清洗后数据 df.to_excel(&#39;cleaned_data.xlsx&#39;, index=False) return df # 使用示例 cleaned_df = clean_excel_data(&#39;raw_data.xlsx&#39;) ``` ## 四、注意事项 1. **填充前分析**:使用 `df.isnull().sum()` 统计缺失值情况 2. **数据类型区分**:数值型、分类型和时间序列数据使用不同策略 3. **避免过度填充**:对于缺失率 >30% 的列应考虑删除而非填充 4. **业务逻辑优先**:遵循领域知识确定填充值(如:库存为空应为 0) ## 五、可视化检测(可选) ```python import seaborn as sns import matplotlib.pyplot as plt # 缺失值热力图 plt.figure(figsize=(10, 6)) sns.heatmap(df.isnull(), cbar=False, cmap=&#39;viridis&#39;) plt.title(&#39;缺失值分布热力图&#39;) plt.savefig(&#39;missing_values_heatmap.png&#39;) ``` 通过以上方法,您可以高效处理 Excel 数据中的空白单元格问题,确保后续分析的准确性。数据清洗是数据分析的基础步骤,良好的清洗实践能显著提升分析结果可靠性[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值