鱼C论坛

 找回密码
 立即注册
查看: 989|回复: 12

[已解决]python操作excel表格

[复制链接]
发表于 2021-11-29 17:53:50 | 显示全部楼层 |阅读模式
10鱼币
不知为何,所发文字含有不良信息,故将需求写进附件中
图片:
001.jpg 002.jpg 003.jpg
附件:
需求与数据.zip (75.56 KB, 下载次数: 4)
  1. import pandas as pd
  2. import openpyxl

  3. file = r"C:\Users\me\Desktop\zwyc.xlsx"

  4. wb_w =openpyxl.load_workbook(file)
  5. sheet = wb_w['对齐大表']

  6. zm = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")   
  7. zm.extend([m+n for m in zm for n in zm])        #生成与excel表格一致的表头

  8. df = pd.read_excel(file,sheet_name='对齐大表',header=None)

  9. row_max = df.shape[0]
  10. col_max = df.shape[1]
  11. df.columns = zm[:col_max]
  12. df.index = df.index+1

  13. qx = '环焊缝异常'    # excel对应的列
  14. col_hhfh = 'U'
  15. col_hfjl = 'V'
  16. col_xygc = 'W'
  17. col_jclc = 'X'
  18. col_tzlb = 'Y'
  19. col_sbqx = 'Z'
  20. col_fh = 'AI'
  21. col_bz = 'AJ'

  22. for row in df.index:
  23.     if df.loc[row][col_tzlb] == qx:
  24.         print(row)
  25.         for up in range(row-1,0,-1):
  26.             if df.loc[up][col_tzlb] == '环焊缝':
  27.                 row_up = up
  28.                 print(row_up)
  29.                 break
  30.         for under in range(row+1,row_max+1,1):
  31.             if df.loc[under][col_tzlb] == '环焊缝':
  32.                 row_under = under
  33.                 print(row_under)
  34.                 break
  35.         dist_up = abs(df.loc[row][col_jclc] - df.loc[row_up][col_jclc])
  36.         dist_under = abs(df.loc[row][col_jclc] - df.loc[row_under][col_jclc])
  37.         if dist_under < dist_up:
  38.             sheet.insert_rows(row_under + 1)        # 插入空行。参数(x,y)x插入的位置,从1开始;y插入的行数
  39.             temp = col_hhfh + str(row) + ":" + col_bz + str(row)      # 拼接移动的区域Excel,例:"A3:J3"
  40.             sheet.move_range(temp,row_under + 1 - row,0)            # 移动数据。(x,y,z)x移动的区域str类型,y移动行数的相对量,移动列数的相对量
  41.             sheet.delete_rows(row)                        # 删除数据移动后的空行
  42. wb_w.save(file)
复制代码
最佳答案
2021-11-29 17:53:51
水平有限,其实逻辑很简单,但是中间和pandas的各种操作斗争了很久,代码写的也比较乱,随便看看,主要是逻辑,具体的你可以自己实现
简单说一下逻辑,当下一次 环焊缝出现时,这次环焊缝到上次环焊缝之间的数据的位置就已经确定了,上次环焊缝后面放的是两次环焊缝之间的所有异常数据里离上次环焊缝距离近的数据(也就是位置在中点偏向上次环焊缝一侧的哪些数据),然后是不是环焊缝异常的数据,然后是这次环焊缝数据,然后是剩下的环焊缝异常数据。说的比较绕,你多看几次。
代码如下
  1. import pandas as pd


  2. def processing(excel_file,output):
  3.     #读取文件并重设表头
  4.     df = pd.read_excel(excel_file,header=None) #不读取表头
  5.     df.columns=[i for i in range(36)]
  6.     df2=pd.DataFrame(columns = [i for i in range(36)]) #重新设置表头(检测里程为23列,特征类别为24列)
  7.     cur_girth_weld = 2  #存放上一个环焊缝数据的行数
  8.     mid=0               #存放当前环焊缝和上一个环焊缝里程数的中值
  9.     error_cache=[]      #存放上一个环焊缝到当前环焊缝中环焊缝异常的行数
  10.     cache=[]            #存放上一个环焊缝到当前环焊缝中不是环焊缝为异常的行数
  11.     df2 = df2.append(df.iloc[2],ignore_index=False, verify_integrity=False, sort=None)
  12.     for row in df.index[2:]:
  13.         
  14.         if df.loc[row,24]=="环焊缝":  #读取到环焊缝,开始处理保存下来的数据
  15.             mid=(df.loc[row,23]+df.loc[cur_girth_weld,23])/2 #求两个环焊缝中点
  16.             while error_cache:
  17.                 if df.iloc[error_cache[0],23]<mid:    #小于重点,则直接放在上一个环焊缝后
  18.                     df2 = df2.append(df.iloc[error_cache[0]],ignore_index=False, verify_integrity=False, sort=None)
  19.                     error_cache.pop(0)
  20.                 else:
  21.                     break   # 因为数据已经排序,所以当大于中点,跳出

  22.             
  23.             for row_c in cache: #存放非行环焊缝异常数据
  24.                 df2 = df2.append(df.iloc[row_c],ignore_index=False, verify_integrity=False, sort=None)
  25.             cache=[]
  26.             df2 = df2.append(df.iloc[row],ignore_index=False, verify_integrity=False, sort=None) #存放当前环焊缝数据
  27.             cur_girth_weld=row
  28.             
  29.             while error_cache:    #存放剩下的环焊缝异常数据
  30.                 df2 = df2.append(df.iloc[error_cache[0]],ignore_index=False, verify_integrity=False, sort=None)
  31.                 error_cache.pop(0)

  32.         elif df.loc[row,24]=="环焊缝异常":
  33.             error_cache.append(row)     #缓存环焊缝异常数据
  34.         else:
  35.             cache.append(row)          #缓存非环焊缝异常数据

  36.     df2.to_excel(output)


  37. if __name__=="__main__":
  38.     processing("zwyc.xlsx","output.xlsx")
  39.         
  40.      
复制代码


最佳答案

查看完整内容

水平有限,其实逻辑很简单,但是中间和pandas的各种操作斗争了很久,代码写的也比较乱,随便看看,主要是逻辑,具体的你可以自己实现 简单说一下逻辑,当下一次 环焊缝出现时,这次环焊缝到上次环焊缝之间的数据的位置就已经确定了,上次环焊缝后面放的是两次环焊缝之间的所有异常数据里离上次环焊缝距离近的数据(也就是位置在中点偏向上次环焊缝一侧的哪些数据),然后是不是环焊缝异常的数据,然后是这次环焊缝数据,然后是剩 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 17:53:51 | 显示全部楼层    本楼为最佳答案   
水平有限,其实逻辑很简单,但是中间和pandas的各种操作斗争了很久,代码写的也比较乱,随便看看,主要是逻辑,具体的你可以自己实现
简单说一下逻辑,当下一次 环焊缝出现时,这次环焊缝到上次环焊缝之间的数据的位置就已经确定了,上次环焊缝后面放的是两次环焊缝之间的所有异常数据里离上次环焊缝距离近的数据(也就是位置在中点偏向上次环焊缝一侧的哪些数据),然后是不是环焊缝异常的数据,然后是这次环焊缝数据,然后是剩下的环焊缝异常数据。说的比较绕,你多看几次。
代码如下
  1. import pandas as pd


  2. def processing(excel_file,output):
  3.     #读取文件并重设表头
  4.     df = pd.read_excel(excel_file,header=None) #不读取表头
  5.     df.columns=[i for i in range(36)]
  6.     df2=pd.DataFrame(columns = [i for i in range(36)]) #重新设置表头(检测里程为23列,特征类别为24列)
  7.     cur_girth_weld = 2  #存放上一个环焊缝数据的行数
  8.     mid=0               #存放当前环焊缝和上一个环焊缝里程数的中值
  9.     error_cache=[]      #存放上一个环焊缝到当前环焊缝中环焊缝异常的行数
  10.     cache=[]            #存放上一个环焊缝到当前环焊缝中不是环焊缝为异常的行数
  11.     df2 = df2.append(df.iloc[2],ignore_index=False, verify_integrity=False, sort=None)
  12.     for row in df.index[2:]:
  13.         
  14.         if df.loc[row,24]=="环焊缝":  #读取到环焊缝,开始处理保存下来的数据
  15.             mid=(df.loc[row,23]+df.loc[cur_girth_weld,23])/2 #求两个环焊缝中点
  16.             while error_cache:
  17.                 if df.iloc[error_cache[0],23]<mid:    #小于重点,则直接放在上一个环焊缝后
  18.                     df2 = df2.append(df.iloc[error_cache[0]],ignore_index=False, verify_integrity=False, sort=None)
  19.                     error_cache.pop(0)
  20.                 else:
  21.                     break   # 因为数据已经排序,所以当大于中点,跳出

  22.             
  23.             for row_c in cache: #存放非行环焊缝异常数据
  24.                 df2 = df2.append(df.iloc[row_c],ignore_index=False, verify_integrity=False, sort=None)
  25.             cache=[]
  26.             df2 = df2.append(df.iloc[row],ignore_index=False, verify_integrity=False, sort=None) #存放当前环焊缝数据
  27.             cur_girth_weld=row
  28.             
  29.             while error_cache:    #存放剩下的环焊缝异常数据
  30.                 df2 = df2.append(df.iloc[error_cache[0]],ignore_index=False, verify_integrity=False, sort=None)
  31.                 error_cache.pop(0)

  32.         elif df.loc[row,24]=="环焊缝异常":
  33.             error_cache.append(row)     #缓存环焊缝异常数据
  34.         else:
  35.             cache.append(row)          #缓存非环焊缝异常数据

  36.     df2.to_excel(output)


  37. if __name__=="__main__":
  38.     processing("zwyc.xlsx","output.xlsx")
  39.         
  40.      
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 18:07:58 | 显示全部楼层
本帖最后由 lightninng 于 2021-11-29 18:10 编辑

两个疑问:
1、你的例子里面离下方更近对吧,如果是离上方那个环焊缝更近是不是就不用移动了?
2、多个环焊缝的情况,要保持原来的顺序嘛,我看你图片里移动后。两个异常的位置前后互换了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 18:11:05 | 显示全部楼层


数据量大嘛,如果单独建一个dataframe然后按顺序把原来的dataframe里得数据插入进去,8G内存跑的起来嘛?
还有刚那个第二个问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-29 18:15:57 | 显示全部楼层
lightninng 发表于 2021-11-29 18:11
数据量大嘛,如果单独建一个dataframe然后按顺序把原来的dataframe里得数据插入进去,8G内存跑的起来嘛 ...

对,其他数据的位置不能动,两个异常移动后的先后位置无所谓,只要保证在距离更近的环焊缝下方
我只截取了表格的一点点数据,跑起来特别慢,所以寻求帮助嘛
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 18:19:12 | 显示全部楼层
来自星星的小明 发表于 2021-11-29 18:15
对,其他数据的位置不能动,两个异常移动后的先后位置无所谓,只要保证在距离更近的环焊缝下方
我只截取 ...

我看你例子也是单个文件一次处理得,并没有把一个文件中的内容分为多个数据,老实说,我不会分批处理,我先试着把它按单个文件处理一下~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-29 18:22:00 | 显示全部楼层
lightninng 发表于 2021-11-29 18:19
我看你例子也是单个文件一次处理得,并没有把一个文件中的内容分为多个数据,老实说,我不会分批处理,我 ...

嗯,这个文件的完整数据有几十兆,像这样的文件有几百个,谢谢你啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 20:42:36 | 显示全部楼层
我很好奇,这样做有什么特殊的意义吗?有必要吗?本质上这是个"排序"问题,
但你给出的截图好像只是对几条数据稍微改变了 一下位置,所以这样做到底是为了啥?

所以,若前提你数据已经正确,那就只是排序问题,那么 就根据 排序条件,df.sort_values(by=[...]) 即可
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 20:56:32 | 显示全部楼层
阿奇_o 发表于 2021-11-29 20:42
我很好奇,这样做有什么特殊的意义吗?有必要吗?本质上这是个"排序"问题,
但你给出的截图好像只是对几条 ...

仔细看一下并不是简单的排序问题,不过其实也差不太多了,我觉得这个问题最大的挑战还是excel的处理。哈哈哈哈哈哈哈哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-30 09:08:55 | 显示全部楼层
阿奇_o 发表于 2021-11-29 20:42
我很好奇,这样做有什么特殊的意义吗?有必要吗?本质上这是个"排序"问题,
但你给出的截图好像只是对几条 ...

之前试过排序,但条件太复杂,结果偏差较大,这张表的完整数据大概有10万多行,130多列,行和列考虑的因素太多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-30 10:35:13 | 显示全部楼层
lightninng 发表于 2021-11-29 17:53
水平有限,其实逻辑很简单,但是中间和pandas的各种操作斗争了很久,代码写的也比较乱,随便看看,主要是逻 ...

逻辑清晰,很nice,按照你的想法,我改改。
疑惑的一点,就是没指定index和行号一致 df.loc() 和 df.iloc()混用的话,会不会有问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-30 11:30:22 | 显示全部楼层
本帖最后由 lightninng 于 2021-11-30 11:35 编辑
来自星星的小明 发表于 2021-11-30 10:35
逻辑清晰,很nice,按照你的想法,我改改。
疑惑的一点,就是没指定index和行号一致 df.loc() 和 df.ilo ...


你可以改一下,老实说,我花时间最多还是append这里,pandas这个索引使用方法自从不让用ix之后,很烦人~~~

另外批量处理表格的话,用os.walk(os.getcwd())读取一下当前目录下的文件,然后用split方法把扩展名分离出来做判断是否为表格,当然os模块里面也有相应的方法,然后调用processing方法就行了~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-30 11:46:37 | 显示全部楼层
lightninng 发表于 2021-11-30 11:30
你可以改一下,老实说,我花时间最多还是append这里,pandas这个索引使用方法自从不让用ix之后,很烦人 ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-1 17:12

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表