鱼C论坛

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

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

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

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

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

x
代码如下:
import pandas as pd
import numpy as np
from datetime import datetime
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter


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


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

# 设置名字选择
namedate1 = df['接听座席']
print(namedate1)
name = []
namedate2 = namedate1.dropna()
namedate3 = namedate2.drop_duplicates()
for sel in namedate3:
    print(sel)
    name.append(sel)
print(name)
print(len(name))



'''
# 分析数据

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

# 设置总人员数据的列表
namedf = []
# 设置星期一到星期五的列表
days1 = []
days2 = []
days3 = []
days4 = []
days5 = []
# 设置每人每日的列表
day1 = []
day2 = []
day3 = []
day4 = []
day5 = []
# 设置星期一到星期五的目标数据的列表
data1 = dict()
data2 = dict()
data3 = dict()
data4 = dict()
data5 = dict()

namea = []
nameb = []
namec = []
named = []
namee = []
        


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

for each_days in namedf:
    days1.append(each_days[each_days['星期'] == 0])
    days2.append(each_days[each_days['星期'] == 1])
    days3.append(each_days[each_days['星期'] == 2])
    days4.append(each_days[each_days['星期'] == 3])
    days5.append(each_days[each_days['星期'] == 4])
    
for each_day1 in days1:
    day1.append(each_day1.drop_duplicates(subset = '接听座席'))
    
for each_day2 in days2:
    day2.append(each_day2.drop_duplicates(subset = '接听座席'))
    
for each_day3 in days3:
    day3.append(each_day3.drop_duplicates(subset = '接听座席'))
    
for each_day4 in days4:
    day4.append(each_day4.drop_duplicates(subset = '接听座席'))
    
for each_day5 in days5:
    day5.append(each_day5.drop_duplicates(subset = '接听座席'))
    
for dayone in day1:
    if len(dayone.index) == 0:
        continue
    name1 = dayone.iat[0,0]
    name2 = name1[:-6]
    namea.append(name2)
    time1 = dayone.iat[0,3]
    time2 = time1[:5]
    data1[name2] = time2
    
for daytwo in day2:
    if len(daytwo.index) == 0:
        continue
    name1 = daytwo.iat[0,0]
    name2 = name1[:-6]
    nameb.append(name2)
    time1 = daytwo.iat[0,3]
    time2 = time1[:5]
    data2[name2] = time2
    
for daythree in day3:
    if len(daythree.index) == 0:
        continue
    name1 = daythree.iat[0,0]
    name2 = name1[:-6]
    namec.append(name2)
    time1 = daythree.iat[0,3]
    time2 = time1[:5]
    data3[name2] = time2
    
for dayfour in day4:
    if len(dayfour.index) == 0:
        continue
    name1 = dayfour.iat[0,0]
    name2 = name1[:-6]
    named.append(name2)
    time1 = dayfour.iat[0,3]
    time2 = time1[:5]
    data4[name2] = time2
    
for dayfive in day5:
    if len(dayfive.index) == 0:
        continue
    name1 = dayfive.iat[0,0]
    name2 = name1[:-6]
    namee.append(name2)
    time1 = dayfive.iat[0,3]
    time2 = time1[:5]
    data5[name2] = time2
    
print('星期一数据:')
print(data1)
print(len(data1))
print('星期二数据:')
print(data2)
print(len(data2))
print('星期三数据:')
print(data3)
print(len(data3))
print('星期四数据:')
print(data4)
print(len(data4))
print('星期五数据:')
print(data5)
print(len(data5))

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

# 打开文件
wb = load_workbook(addr)


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




for d5 in range(len(data5)):
    ws.cell(d5+2,1).value = namee[d5]
    ws.cell(d5+2,2).value = data5[namee[d5]]
for d1 in range(len(data1)):
    ws.cell(d1+2,3).value = namea[d1]
    ws.cell(d1+2,4).value = data1[namea[d1]]
for d2 in range(len(data2)):
    ws.cell(d2+2,5).value = nameb[d2]
    ws.cell(d2+2,6).value = data2[nameb[d2]]
for d3 in range(len(data3)):
    ws.cell(d3+2,7).value = namec[d3]
    ws.cell(d3+2,8).value = data3[namec[d3]]
for d4 in range(len(data4)):
    ws.cell(d4+2,9).value = named[d4]
    ws.cell(d4+2,10).value = data4[named[d4]]

wb.save(addr)

感觉很多都重复,但是想不到怎么优化,有大神给个思路吗?最好是优化后的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-10 20:23:17 | 显示全部楼层
直接把可以复用的都封装成一个函数,然后每个函数去单独调用,这样就精简了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

变量需要几个,封装成函数我不大会搞,有思路或者例子吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-13 10:53:16 From FishC Mobile | 显示全部楼层
先写类,划到类的各种属性,再通过主程序传进去
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你可以发下需求&示例的数据。
想知道小甲鱼最近在做啥?请访问 -> 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                                                       
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


微信图片_20200813130813.png
点击这里可以上传文件,
数据源以及对应什么需求?要做什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

原始数据大概:

                               
登录/注册后可看大图


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

                               
登录/注册后可看大图



我等级不够,没有附件功能,不好意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

弄的方法知道,excel的话,原始数据会有好几W以上 的,估计不快把。Python我是写出来了,就想优化下代码,然而我想不到怎么优化,感觉能优化,想求大佬看看怎么优化这样。因为我写的代码感觉都是差不多这类型,要不停开多个列表这样。。。
想知道小甲鱼最近在做啥?请访问 -> 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-最后一行(取最后一行会吧...),每一行的坐席列找到后,判断时间列改为日期,对应到对应的字典,然后判断字典对应坐席的值是否大于当前值,一直修改为最大值。
所以只要循环一次,就能得到最后的字典结果;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-19 11:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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