安全兔 发表于 2020-8-10 18:13:52

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

代码如下:
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 == 'yan(1025)']
# 分切日期和时间便于查找
df1['日期'] = df1['呼叫时间'].apply(lambda x: str(x).split()).astype('datetime64')
df1['时间'] = df1['呼叫时间'].apply(lambda x: str(x).split())
# 解析具体日期
df2 = df1 == datetime(2020,7,24)]
# 筛选第一个
df3 = df2.drop_duplicates(subset = '接听座席')
# 提取目的数据
dname = df3.iat
dtimetemp = df3.iat
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 == each_name])
for each_time in namedf:
    each_time['日期'] = each_time['呼叫时间'].apply(lambda x: str(x).split()).astype('datetime64')
    each_time['时间'] = each_time['呼叫时间'].apply(lambda x: str(x).split())
    each_time['星期'] = each_time['呼叫时间'].dt.dayofweek

for each_days in namedf:
    days1.append(each_days == 0])
    days2.append(each_days == 1])
    days3.append(each_days == 2])
    days4.append(each_days == 3])
    days5.append(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
    name2 = name1[:-6]
    namea.append(name2)
    time1 = dayone.iat
    time2 = time1[:5]
    data1 = time2
   
for daytwo in day2:
    if len(daytwo.index) == 0:
      continue
    name1 = daytwo.iat
    name2 = name1[:-6]
    nameb.append(name2)
    time1 = daytwo.iat
    time2 = time1[:5]
    data2 = time2
   
for daythree in day3:
    if len(daythree.index) == 0:
      continue
    name1 = daythree.iat
    name2 = name1[:-6]
    namec.append(name2)
    time1 = daythree.iat
    time2 = time1[:5]
    data3 = time2
   
for dayfour in day4:
    if len(dayfour.index) == 0:
      continue
    name1 = dayfour.iat
    name2 = name1[:-6]
    named.append(name2)
    time1 = dayfour.iat
    time2 = time1[:5]
    data4 = time2
   
for dayfive in day5:
    if len(dayfive.index) == 0:
      continue
    name1 = dayfive.iat
    name2 = name1[:-6]
    namee.append(name2)
    time1 = dayfive.iat
    time2 = time1[:5]
    data5 = 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
    ws.cell(d5+2,2).value = data5]
for d1 in range(len(data1)):
    ws.cell(d1+2,3).value = namea
    ws.cell(d1+2,4).value = data1]
for d2 in range(len(data2)):
    ws.cell(d2+2,5).value = nameb
    ws.cell(d2+2,6).value = data2]
for d3 in range(len(data3)):
    ws.cell(d3+2,7).value = namec
    ws.cell(d3+2,8).value = data3]
for d4 in range(len(data4)):
    ws.cell(d4+2,9).value = named
    ws.cell(d4+2,10).value = data4]

wb.save(addr)

感觉很多都重复,但是想不到怎么优化,有大神给个思路吗?最好是优化后的

小小小菜菜菜 发表于 2020-8-10 20:23:17

直接把可以复用的都封装成一个函数,然后每个函数去单独调用,这样就精简了

安全兔 发表于 2020-8-13 10:41:49

小小小菜菜菜 发表于 2020-8-10 20:23
直接把可以复用的都封装成一个函数,然后每个函数去单独调用,这样就精简了

变量需要几个,封装成函数我不大会搞,有思路或者例子吗?

Py与C。。。 发表于 2020-8-13 10:53:16

先写类,划到类的各种属性,再通过主程序传进去

yhhpf 发表于 2020-8-13 11:27:31

设置列表时可以循环5次,输出days、day、data、name对应的5个列表,以及后面循环的语句应该都可以优化;

你可以发下需求&示例的数据。

安全兔 发表于 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                                                       

yhhpf 发表于 2020-8-13 13:09:03

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





点击这里可以上传文件,
数据源以及对应什么需求?要做什么?

安全兔 发表于 2020-8-13 14:11:35

yhhpf 发表于 2020-8-13 13:09
点击这里可以上传文件,
数据源以及对应什么需求?要做什么?

原始数据大概:
http://qungz.photo.store.qq.com/qun-qungz/69a4501e-e14a-46f0-8241-fed24ff7b678/V5bCAAxNzUyNTUxMI3YNF.VT68x/800?w5=565&h5=163&rf=viewer_421

需求是提取接听坐席,和每天单个人员最后出现时间
http://qungz.photo.store.qq.com/qun-qungz/69a4501e-e14a-46f0-8241-fed24ff7b678/V5bCAAxNzUyNTUxMCjZNF9ZwO46/800?w5=417&h5=91&rf=viewer_421


我等级不够,没有附件功能,不好意思

yhhpf 发表于 2020-8-13 15:37:20

安全兔 发表于 2020-8-13 14:11
原始数据大概:




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

安全兔 发表于 2020-8-13 16:21:38

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

弄的方法知道,excel的话,原始数据会有好几W以上 的,估计不快把。Python我是写出来了,就想优化下代码,然而我想不到怎么优化,感觉能优化,想求大佬看看怎么优化这样。因为我写的代码感觉都是差不多这类型,要不停开多个列表这样。。。

yhhpf 发表于 2020-8-13 16:42:13

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

你看我回你的,使用字典呀,直接循环读取表格数据作判断,不用读到列表里。也就不用重复那么多了。
坐席是确认那几个的吧,直接for循环按日期创建多个字典(dict_日期 = {'a':0,'b':0,'c':0..........},这里的日期按你实际的来),然后循环2-最后一行(取最后一行会吧...),每一行的坐席列找到后,判断时间列改为日期,对应到对应的字典,然后判断字典对应坐席的值是否大于当前值,一直修改为最大值。
所以只要循环一次,就能得到最后的字典结果;
页: [1]
查看完整版本: 我写了一个小功能,但是感觉很臃肿,有大神指点下怎么优化下代码会简化很多