鱼C论坛

 找回密码
 立即注册
查看: 1891|回复: 10

我写了一个小功能,但是感觉很臃肿,有大神指点下怎么优化下代码会简化很多

[复制链接]
发表于 2020-8-10 18:13:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码如下:
  1. import pandas as pd
  2. import numpy as np
  3. from datetime import datetime
  4. from openpyxl import load_workbook
  5. from openpyxl.utils import get_column_letter


  6. # 打开文件位置
  7. fpath = r'E:\test\打卡整理\至联0731-0806.csv'
  8. # header是第0行作为“列名”,读取数据存在名为df的DataFrame中
  9. df = pd.read_csv(fpath,header = 0,index_col = None,encoding = 'gbk',low_memory=False)
  10. # 修改时间未datatime
  11. df['呼叫时间'] = pd.to_datetime(df['呼叫时间'])


  12. # 提取目标数据
  13. date = df[['接听座席','呼叫时间']]

  14. # 设置名字选择
  15. namedate1 = df['接听座席']
  16. print(namedate1)
  17. name = []
  18. namedate2 = namedate1.dropna()
  19. namedate3 = namedate2.drop_duplicates()
  20. for sel in namedate3:
  21.     print(sel)
  22.     name.append(sel)
  23. print(name)
  24. print(len(name))



  25. '''
  26. # 分析数据

  27. # 解析单个坐席
  28. df1 = date.loc[date['接听座席'] == 'yan(1025)']
  29. # 分切日期和时间便于查找
  30. df1['日期'] = df1['呼叫时间'].apply(lambda x: str(x).split()[0]).astype('datetime64')
  31. df1['时间'] = df1['呼叫时间'].apply(lambda x: str(x).split()[1])
  32. # 解析具体日期
  33. df2 = df1[df1['日期'] == datetime(2020,7,24)]
  34. # 筛选第一个
  35. df3 = df2.drop_duplicates(subset = '接听座席')
  36. # 提取目的数据
  37. dname = df3.iat[0,0]
  38. dtimetemp = df3.iat[0,3]
  39. ditme = dtimetemp[:5]
  40. '''

  41. # 设置总人员数据的列表
  42. namedf = []
  43. # 设置星期一到星期五的列表
  44. days1 = []
  45. days2 = []
  46. days3 = []
  47. days4 = []
  48. days5 = []
  49. # 设置每人每日的列表
  50. day1 = []
  51. day2 = []
  52. day3 = []
  53. day4 = []
  54. day5 = []
  55. # 设置星期一到星期五的目标数据的列表
  56. data1 = dict()
  57. data2 = dict()
  58. data3 = dict()
  59. data4 = dict()
  60. data5 = dict()

  61. namea = []
  62. nameb = []
  63. namec = []
  64. named = []
  65. namee = []
  66.         


  67. for each_name in name:
  68.     namedf.append(date.loc[date['接听座席'] == each_name])
  69. for each_time in namedf:
  70.     each_time['日期'] = each_time['呼叫时间'].apply(lambda x: str(x).split()[0]).astype('datetime64')
  71.     each_time['时间'] = each_time['呼叫时间'].apply(lambda x: str(x).split()[1])
  72.     each_time['星期'] = each_time['呼叫时间'].dt.dayofweek

  73. for each_days in namedf:
  74.     days1.append(each_days[each_days['星期'] == 0])
  75.     days2.append(each_days[each_days['星期'] == 1])
  76.     days3.append(each_days[each_days['星期'] == 2])
  77.     days4.append(each_days[each_days['星期'] == 3])
  78.     days5.append(each_days[each_days['星期'] == 4])
  79.    
  80. for each_day1 in days1:
  81.     day1.append(each_day1.drop_duplicates(subset = '接听座席'))
  82.    
  83. for each_day2 in days2:
  84.     day2.append(each_day2.drop_duplicates(subset = '接听座席'))
  85.    
  86. for each_day3 in days3:
  87.     day3.append(each_day3.drop_duplicates(subset = '接听座席'))
  88.    
  89. for each_day4 in days4:
  90.     day4.append(each_day4.drop_duplicates(subset = '接听座席'))
  91.    
  92. for each_day5 in days5:
  93.     day5.append(each_day5.drop_duplicates(subset = '接听座席'))
  94.    
  95. for dayone in day1:
  96.     if len(dayone.index) == 0:
  97.         continue
  98.     name1 = dayone.iat[0,0]
  99.     name2 = name1[:-6]
  100.     namea.append(name2)
  101.     time1 = dayone.iat[0,3]
  102.     time2 = time1[:5]
  103.     data1[name2] = time2
  104.    
  105. for daytwo in day2:
  106.     if len(daytwo.index) == 0:
  107.         continue
  108.     name1 = daytwo.iat[0,0]
  109.     name2 = name1[:-6]
  110.     nameb.append(name2)
  111.     time1 = daytwo.iat[0,3]
  112.     time2 = time1[:5]
  113.     data2[name2] = time2
  114.    
  115. for daythree in day3:
  116.     if len(daythree.index) == 0:
  117.         continue
  118.     name1 = daythree.iat[0,0]
  119.     name2 = name1[:-6]
  120.     namec.append(name2)
  121.     time1 = daythree.iat[0,3]
  122.     time2 = time1[:5]
  123.     data3[name2] = time2
  124.    
  125. for dayfour in day4:
  126.     if len(dayfour.index) == 0:
  127.         continue
  128.     name1 = dayfour.iat[0,0]
  129.     name2 = name1[:-6]
  130.     named.append(name2)
  131.     time1 = dayfour.iat[0,3]
  132.     time2 = time1[:5]
  133.     data4[name2] = time2
  134.    
  135. for dayfive in day5:
  136.     if len(dayfive.index) == 0:
  137.         continue
  138.     name1 = dayfive.iat[0,0]
  139.     name2 = name1[:-6]
  140.     namee.append(name2)
  141.     time1 = dayfive.iat[0,3]
  142.     time2 = time1[:5]
  143.     data5[name2] = time2
  144.    
  145. print('星期一数据:')
  146. print(data1)
  147. print(len(data1))
  148. print('星期二数据:')
  149. print(data2)
  150. print(len(data2))
  151. print('星期三数据:')
  152. print(data3)
  153. print(len(data3))
  154. print('星期四数据:')
  155. print(data4)
  156. print(len(data4))
  157. print('星期五数据:')
  158. print(data5)
  159. print(len(data5))

  160. # 设置路径
  161. addr = r'E:\test\打卡整理\0724-0731RCB LastCall.xlsx'

  162. # 打开文件
  163. wb = load_workbook(addr)


  164. # 选择表
  165. ws = wb['Sheet2']
  166. # 第一行输入标题
  167. ws.append(['星期五数据:',None,'星期一数据:',None,'星期二数据:',None,
  168.            '星期三数据:',None,'星期四数据:',None])




  169. for d5 in range(len(data5)):
  170.     ws.cell(d5+2,1).value = namee[d5]
  171.     ws.cell(d5+2,2).value = data5[namee[d5]]
  172. for d1 in range(len(data1)):
  173.     ws.cell(d1+2,3).value = namea[d1]
  174.     ws.cell(d1+2,4).value = data1[namea[d1]]
  175. for d2 in range(len(data2)):
  176.     ws.cell(d2+2,5).value = nameb[d2]
  177.     ws.cell(d2+2,6).value = data2[nameb[d2]]
  178. for d3 in range(len(data3)):
  179.     ws.cell(d3+2,7).value = namec[d3]
  180.     ws.cell(d3+2,8).value = data3[namec[d3]]
  181. for d4 in range(len(data4)):
  182.     ws.cell(d4+2,9).value = named[d4]
  183.     ws.cell(d4+2,10).value = data4[named[d4]]

  184. wb.save(addr)
复制代码


感觉很多都重复,但是想不到怎么优化,有大神给个思路吗?最好是优化后的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-10 20:23:17 | 显示全部楼层
直接把可以复用的都封装成一个函数,然后每个函数去单独调用,这样就精简了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-13 10:41:49 | 显示全部楼层
小小小菜菜菜 发表于 2020-8-10 20:23
直接把可以复用的都封装成一个函数,然后每个函数去单独调用,这样就精简了

变量需要几个,封装成函数我不大会搞,有思路或者例子吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-13 10:53:16 From FishC Mobile | 显示全部楼层
先写类,划到类的各种属性,再通过主程序传进去
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-13 11:27:31 | 显示全部楼层
设置列表时可以循环5次,输出days、day、data、name对应的5个列表,以及后面循环的语句应该都可以优化;

你可以发下需求&示例的数据。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-13 12:19:05 | 显示全部楼层
yhhpf 发表于 2020-8-13 11:27
设置列表时可以循环5次,输出days、day、data、name对应的5个列表,以及后面循环的语句应该都可以优化;

...

数据我随便写了,也差不多这样子,不懂上传文件


用户        接听坐席        客户                呼叫时间                        结束时间                满意度                最终结果:        星期三数据:        星期四数据:       
  1          a(101)                  2020\7\30 21:04          2020\7\27 19:07          2                                                a        21:04        d        10:19
  2          b(102)                  2020\7\30 21:04          2020\7\27 19:07          22                                                b        21:04        a        10:19
  3          c(104)        先生          2020\7\30 21:03          2020\7\27 19:07          2222                                        c        21:03        c        10:33
  4          d(105)                  2020\7\29 10:19          2020\7\27 19:07          22222                                                                b        10:33
          a(101)                  2020\7\29 10:19          2020\7\27 10:33                                                       
          c(104)                  2020\7\29 10:33          2020\7\27 10:33                                                       
          c(104)                  2020\7\29 10:19          2020\7\27 10:33                                                       
          b(102)                  2020\7\29 10:33          2020\7\27 10:33                                                       
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-13 13:09:03 | 显示全部楼层
安全兔 发表于 2020-8-13 12:19
数据我随便写了,也差不多这样子,不懂上传文件


微信图片_20200813130813.png
点击这里可以上传文件,
数据源以及对应什么需求?要做什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-13 14:11:35 | 显示全部楼层
yhhpf 发表于 2020-8-13 13:09
点击这里可以上传文件,
数据源以及对应什么需求?要做什么?

原始数据大概:

                               
登录/注册后可看大图


需求是提取接听坐席,和每天单个人员最后出现时间

                               
登录/注册后可看大图



我等级不够,没有附件功能,不好意思
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-13 15:37:20 | 显示全部楼层

这个用excel的话,时间降序排列+呼叫时间取日期+删除坐席&日期连接的重复项估计1分钟都不用- -...
写vba也简单
用python 反而麻烦了,python 的思路的话:设置每个星期的几个空表,的字典,坐席取唯一值作为key,然后循环坐席下来,判断对应呼叫时间的日期到对应字典,比较字典key的值两者那个最大,保留最大的。循环到底结束。
额~~~我知道的方法里用Python实现麻烦...
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-13 16:21:38 | 显示全部楼层
yhhpf 发表于 2020-8-13 15:37
这个用excel的话,时间降序排列+呼叫时间取日期+删除坐席&日期连接的重复项估计1分钟都不用- -...
写vba ...

弄的方法知道,excel的话,原始数据会有好几W以上 的,估计不快把。Python我是写出来了,就想优化下代码,然而我想不到怎么优化,感觉能优化,想求大佬看看怎么优化这样。因为我写的代码感觉都是差不多这类型,要不停开多个列表这样。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-13 16:42:13 | 显示全部楼层
安全兔 发表于 2020-8-13 16:21
弄的方法知道,excel的话,原始数据会有好几W以上 的,估计不快把。Python我是写出来了,就想优化下代码 ...

你看我回你的,使用字典呀,直接循环读取表格数据作判断,不用读到列表里。也就不用重复那么多了。
坐席是确认那几个的吧,直接for循环按日期创建多个字典(dict_日期 = {'a':0,'b':0,'c':0..........},这里的日期按你实际的来),然后循环2-最后一行(取最后一行会吧...),每一行的坐席列找到后,判断时间列改为日期,对应到对应的字典,然后判断字典对应坐席的值是否大于当前值,一直修改为最大值。
所以只要循环一次,就能得到最后的字典结果;
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-19 13:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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