• 【实战】再见Excel,我能自由定制表格


      很多开发者说自从有了 Python/Pandas,Excel 都不怎么用了,用它来处理与可视化表格非常快速。

      下面我来举几个例子。

      1. 删除重复行和空行

      我们直接用dict.fromkeys的方法把当前的数据转为字典,默认的值为None因为用不到,也就无所谓了。然后我们再用list直接对结果进行类型转换,转换为list。

      In [135]:

      for row in rows4:

      print(row)

      ('name', 'address')

      ('tom li', 'beijing')

      ('tom li', 'beijing')

      ('',)

      ('mary wang', 'shandong')

      ('mary wang', 'shandong')

      ('',)

      ('de8ug', 'guangzhou')

      In [148]:

      dict.fromkeys(rows4)

      Out[148]:

      {('name', 'address'): None,

      ('tom li', 'beijing'): None,

      ('',): None,

      ('mary wang', 'shandong'): None,

      ('de8ug', 'guangzhou'): None}

      In [137]:

      list(dict.fromkeys(rows4))

      Out[137]:

      [('name', 'address'),

      ('tom li', 'beijing'),

      ('',),

      ('mary wang', 'shandong'),

      ('de8ug', 'guangzhou')]

      这时候,重复数据直接去掉了,注意我们这里的dict是python3新版本的,所以顺序没有影响,如果你还在用python2或者python3.5以下,建议升级一下python版本。

      接下来,就是空数据的处理了。观察('',)是个元组,第一个位置的数据为空字符串,那么整体长度为1,可以直接通过循环来去掉。这里的循环我们可以用Python中的语法糖写法,直接一行搞定,最后加个判断只留下长度大于1,最后用list转换为列表。

      In [179]:

      list(x for x in dict.fromkeys(rows4) if len(x[0])>1)

      Out[179]:

      [('name', 'address'),

      ('tom li', 'beijing'),

      ('mary wang', 'shandong'),

      ('de8ug', 'guangzhou')]

      上面的研究搞定了,直接把研究结果放到函数中解决重复行和空行的问题。

      注意这时候我们处理的行数据,所以就不再按列循环了。而且,当前的sheet中处理之后,每一行的内容都会修改位置或删除。所以我们先用old_rows = [x for x in sheet.values]取到旧的每一行的数据,注意这里的sheet后直接用values取到数据,而不是cell对象。这里的old_rows是个列表,就可以用刚才的研究直接转为删除重复和空行的数据了。

      接下来,用sheet.delete_rows(1, sheet.max_row)

      删除所有行,第一个参数表示从第一行开始,第二个参数为最大行数。最后,用循环新的行数据的方式,把新数据写入当前的sheet。

      In [189]:

      def handle_duplicate(wb, sheetname):

      """

      去除重复行,空行

      先取出每一行,清空sheet,处理后写回

      """

      print(f'开始处理工作表:{sheetname}'.center(18, '-'))

      sheet = wb[sheetname]

      old_rows = [x for x in sheet.values]

      print('修改前:', old_rows)

      new_rows = list(x for x in dict.fromkeys(old_rows) if len(x[0])>1)

      print('修改后-》》', new_rows)

      # 删除所有行

      sheet.delete_rows(1, sheet.max_row)

      # 写入新数据

      for row in new_rows:

      sheet.append(row)

      运行测试,查看结果。再说一次,一定记得测试啊!如果有错误就根据错误提示,查看代码,反复调试,去除bugs。

      In [190]:

      wb = load_data()

      handle_duplicate(wb, '重复行')

      save_as(wb)

      2.删除空格

      删除空格也需要用到字符串的函数,所以这里还是简单研究一下。如果我们想去除字符串中间的空格,可以用split默认进行分割,然后把分割的结果用’’.join方法连接起来就可以了。注意join前是空的字符串。这里也用不到strip去除两端的空格了,因为split分割后只有几个最后的字符串组成的列表。

      In [192]:

      a="a b c "

      In [194]:

      a.strip()

      Out[194]:

      'a b c'

      In [195]:

      a.split()

      Out[195]:

      ['a', 'b', 'c']

      In [196]:

      ''.join(a.split())

      Out[196]:

      'abc'

      In [ ]:

      研究成功后,写入函数。这次命名为handle_blank。

      In [197]:

      def handle_blank(wb, sheetname):

      """

      按列循环, 通过参数确认目标

      """

      print(f'开始处理工作表:{sheetname}'.center(18, '-'))

      sheet = wb[sheetname]

      for col in sheet.iter_cols(): # 不加参数,循环所有列

      for cell in col:

      print('修改前:', cell.value, end='')

      cell.value = ''.join(cell.value.split())

      print('修改后-》》',cell.value)

      In [198]:

      handle_blank(wb, '空格')

      3.修改日期和时间格式

      有时候,我们需要对表格中时间相关的单元格进行格式修改,这里需要用到Python中时间模块datetime,将需要的格式进行拼接后,用strftime进行转换。

      假设这里我们想把之前简单的1/11月日格式,更改为年月日的样式,中间加上分隔符/或-,就需要用"%x"或"%Y-%m-%d"来进行操作了。注意这里的%加字母都是官方定义好的格式而已,我们用到时候进行拼接,传给函数就可以了。

      具体更多的拼接格式如下:

      In [199]:

      import datetime

      In [209]:

      d=datetime.datetime(2019,1,11)

      In [203]:

      d.strftime("%x")

      Out[203]:

      '01/11/19'

      In [205]:

      d.strftime("%Y-%m-%d")

      Out[205]:

      '2019-01-11'

      研究完成后,我们编写函数。

      首先需要用m, d = cell.value.split('/')把之前简单的日期进行分割,得到m,代表月份和日期,然后用datetime进行转换,生成时间相关的对象day,注意里面的参数是数字,所以用int转换,最后把day进行格式化输出。编写函数后,一定记得测试。

      In [218]:

      def handle_time(wb, sheetname):

      """

      按列循环, 通过参数确认目标

      """

      print(f'开始处理工作表:{sheetname}'.center(18, '-'))

      sheet = wb[sheetname]

      for col in sheet.iter_cols(max_col=1, min_row=2): # 找到时间的列, 第一列,从第二行开始

      for cell in col:

      print('修改前:', cell.value, end='')

      m, d = cell.value.split('/')

      day = datetime.datetime(2019, int(m), int(d))

      cell.value = day.strftime("%Y-%m-%d")

      print('修改后-》》',cell.value)

      In [220]:

      wb = load_data()

      handle_time(wb, '时间')

      save_as(wb)

      4.修复数字和符号

      接下来,处理数字和符号相关的操作。加入我们之前的价格,很多是有小数点的,这时候还想保存两位小数,并加上人民币符号为前缀。就需要新的一波研究了。

      有小数点,一是要保证位数,我们这里要求2位,二是要对多余的位数四舍五入。可以有以下俩个方式完成,一个用Decimal一个用round,两个的区别是Decimal("0.00")指定位数后,会自动补0,而round遇到0就自动舍掉了。而且round在四舍五入的计算中,还有点特殊。具体可查看官方文档。

      我们这里用Decimal来完成函数内相关操作。记得测试啊!

      In [227]:

      from decimal import Decimal

      In [240]:

      a = 3.1

      b=Decimal(a).quantize(Decimal("0.00"))

      print(b)

      3.10

      In [244]:

      round(a,2) # 位数自动省略0

      Out[244]:

      3.1

      In [247]:

      def handle_num(wb, sheetname):

      """

      按列循环, 通过参数确认目标

      """郑州男科医院:http://www.63556355.com/郑州看男科哪家好:http://www.63556355.com/郑州割包皮多少钱:http://www.63556355.com/

      print(f'开始处理工作表:{sheetname}'.center(18, '-'))

      sheet = wb[sheetname]

      for col in sheet.iter_cols(min_col=3, max_col=3, min_row=2): # 找到时间的列, 第一列,从第二行开始

      for cell in col:

      print('修改前:', cell.value, end='')

      # cell.value = round(float(cell.value), 3)

      cell.value = '¥' + str(Decimal(cell.value).quantize(Decimal("0.00")))

      print('修改后-》》',cell.value)

      In [249]:

      wb = load_data()

      handle_num(wb, '数字符号')

      save_as(wb)

  • 相关阅读:
    串口RS232和485通信的波形分析
    Ubuntu添加中文输入法
    虚拟机桥接模式联网方法,Xshell的连接与使用
    waitpid 函数详解
    linux for循环 fork() 产生子进程
    【LeetCode解题总结】动态规划篇
    【LeetCode解题总结】递归篇
    【LeetCode解题总结】排序篇
    【LeetCode解题总结】树/图篇
    【LeetCode解题总结】栈/队列篇
  • 原文地址:https://www.cnblogs.com/sushine1/p/11557075.html
Copyright © 2020-2023  润新知