python语言处理:读取拆分excel中sheet的某列,保存原结构于新sheet中

本文介绍了如何使用Python的pandas和xlrd库以及SQL(包括MySQL模拟)来拆分Excel文件中特定列的长字符,同时保持其他列数据不变。提供了两种处理方式:一是Python脚本读取和写入,二是利用pyspark和SQL进行数据操作。
摘要由CSDN通过智能技术生成

python语言处理:读取拆分excel中sheet的某列,保存原结构于新sheet中

问题描述:

​ 在工作中,接收到Excel文件数据如下图所示,某一列(下图C列)是按照特定字符串联的长字符,但是需求让我们把这列拆分,且在保留同一行其他列数据不变的情况下。
在这里插入图片描述

​ 这里提供python、sql脚本两种处理方式。处理后的需求数据如下图所示。
在这里插入图片描述

处理方式1:

​ 这里利用python,设计两个函数。其中,read_excel_sheet()读取函数,负责读取拆分数据;save_table_to_sheet()写入函数,负责保存拆分数据。具体脚本如下:

# -*- coding: utf-8 -*-
import datetime
import xlrd
from xlutils import copy
import numpy as np

def read_excel_sheet(read_file_name):
    # 01 读取excel数据
    try:
        # 打开excel表格
        data_excel = xlrd.open_workbook(r'{}'.format(read_file_name))
        table = data_excel.sheets()[0]      # 打开第一个sheet1
        # 返回某行中所有单元格的数据组成的列表
        row_data = table.row_values(0, start_colx=0, end_colx=None)
        n_rows = table.nrows  # 获取该sheet中的有效行数
        n_cols = table.ncols  # 获取该sheet中的有效列数

        # 定义存储列表
        data_list = []
        # 需要拆分的列为第3列
        for i in range(1, n_rows):
            # 定义未拆分前的 每行存储列表
            row_list = []

            cell0 = table.cell_value(rowx=i, colx=0)
            cell1 = table.cell_value(rowx=i, colx=1)
            cell2 = table.cell_value(rowx=i, colx=2)
            cell3 = table.cell_value(rowx=i, colx=3)

            column_3_list = cell2.split(',')    # 拆分第三列
            num_col_3 = len(column_3_list)      # 所拆分第三列的长度

            for j in range(num_col_3):
                split_row = [cell0,cell1,column_3_list[j],cell3]
                row_list.append(split_row)  # 列的拆分行加入row_list

            data_list.extend(row_list)  # 汇总行每一行扩展入data_list

        print(data_list)
        now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print('{}>>> Excel数据已经读取,列数据已经拆分!'.format(now))
        return data_list
    except Exception as e:
        print(e)

def save_table_to_sheet(table_list,file_name):
    # 02 写入excel数据
    try:
        # book = xlwt.Workbook(encoding='utf-8', style_compression=0)  # 打开已有excel表格类型文件
        old_book = xlrd.open_workbook(r'{}'.format(read_file_name))
        new_book = copy.copy(old_book)      # 复制文本并保留格式
        sheet1 = new_book.get_sheet(1)      # 打开表单

        table = old_book.sheets()[0]  # 打开第一个sheet1
        # 返回某行中所有单元格的数据组成的列表——标题行
        row_title = table.row_values(0, start_colx=0, end_colx=None)
        table_list.insert(0,row_title)  # 首行插入标题行

        # 列名称设置
        # col_name = table_list[0]
        table_list_num = np.array(table_list)  # np_var_sheet2
        rows = table_list_num.shape[0]  # 输出行
        cols = table_list_num.shape[1]  # 输出列
        # 数据写入
        for i in range(0, rows):
            for j in range(0, cols):
                sheet1.write(i, j, table_list[i][j])
        now = datetime.datetime.now().strftime('%Y%m%d %H:%M:%S')
        new_book.save(file_name)
        print('{}>>> 数据已经写入!'.format(now))
    except Exception as e:
        print(e)

if __name__=='__main__':
    read_file_name = r'D:\test_data\拆分列数据.xls'
    data_list = read_excel_sheet(read_file_name)
    save_table_to_sheet(data_list,read_file_name)
处理方式2:

​ 这里利用mysql,进行数据列拆分,为了方便(作者本人)以本地pyspark模拟mysql环境,进行sql脚本的测试。主要思想是:

  • 首先,借助pandas读取Excel文件,并转化为rdd
  • 然后,创建两个sql视图:tmp_table主表、help_topic辅助表
  • 最后,进行sql执行,再转为pandas并保存为Excel

具体脚本如下:

# -*- coding: utf-8 -*-
import datetime
from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StringType, IntegerType
import pandas as pd
from pyspark.sql import functions as F


if __name__ == '__main__':
    # 0. 构建执行环境入口对象SparkSession
    spark = SparkSession.builder.\
        appName("test").\
        master("local[*]").\
        config("spark.sql.shuffle.partitions", 2).\
        getOrCreate()
    sc = spark.sparkContext

    # 1. 构建rdd
    # 利用pandas读取excel文件,构建一个rdd
    pd_df = pd.read_excel(r'D:\test_data\拆分列数据.xls', sheet_name='Sheet1')
    # 转化为spark格式
    df = spark.createDataFrame(pd_df)

    #  创建另一个rdd,模拟mysql数据库中的mysql.help_topic表的id
    data_list = []
    for i in range(1000):
        data_list.append(i)
    pd_2_df = pd.DataFrame(data_list)
    df_id = spark.createDataFrame(pd_2_df, schema=['help_topic_id'])

    #  创建sql视图1
    df.createOrReplaceTempView('tmp_table')

    # 2. 创建视图
    #  创建sql视图2
    df_id.createOrReplaceTempView('help_topic')

    # 3. sql脚本执行
    result = spark.sql("""
        SELECT xh, table_name,
            SUBSTRING_INDEX(SUBSTRING_INDEX(tb.column_names,',',b.help_topic_id + 1),',',- 1) AS column_names
        FROM
            (SELECT * FROM tmp_table) tb
            JOIN help_topic b ON b.help_topic_id <
             (LENGTH(tb.column_names) - LENGTH(
            REPLACE(tb.column_names, ',', '')) + 1)
        ;
    """).show(truncate=False)


    result_rdd = spark.sql("""
            SELECT xh, table_name,
                SUBSTRING_INDEX(SUBSTRING_INDEX(tb.column_names,',',b.help_topic_id + 1),',',- 1) AS column_names
            FROM
                (SELECT * FROM tmp_table) tb
                JOIN help_topic b ON b.help_topic_id <
                 (LENGTH(tb.column_names) - LENGTH(
                REPLACE(tb.column_names, ',', '')) + 1)
            ;
        """)

    # 4. 数据保存
    #  pandas.DataFrame 转换成 spark.DataFrame
    pandas_df = result_rdd.toPandas()

    #  利用pandas进行保存至Excel中
    pandas_df.to_excel(r'D:\test_data\拆分列数据.xls',sheet_name='Sheet3',
                      index=False)

    now = datetime.datetime.now().strftime('%Y%m%d %H:%M:%S')
    print('{}>>>> 数据已经保存'.format(now))
小贴士:

在真实的mysql环境下,脚本为:

SELECT 
	xh, table_name,
    SUBSTRING_INDEX(SUBSTRING_INDEX(tb.column_names,',',b.help_topic_id + 1),',',- 1) AS column_names
FROM
    (SELECT * FROM tmp_table) tb
     JOIN mysql.help_topic b ON b.help_topic_id <
     (LENGTH(tb.column_names) - LENGTH(
     REPLACE(tb.column_names, ',', '')) + 1)
        ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值