找回密码
 立即注册
搜索
热搜: Excel discuz
查看: 5212|回复: 4

[项目代码] 斑马救援出勤统计代码

[复制链接]

497

主题

7万

元宝

78万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
784980
发表于 2021-10-2 19:37:50 | 显示全部楼层 |阅读模式
内容来源于更早的一篇帖子 http://zhaoqianzhou.com/forum.php?mod=viewthread&tid=261&extra=page%3D6

  1. from openpyxl import Workbook                         #导入Excel模块
  2. wb = Workbook()                                  #创建一个Excel文件
  3. sheet = wb.active                                  #获取当前sheet名称
  4. sheet.title = "第一个sheet"                          #修改sheet名称
  5. sheet['A1']= "姓名"                                    #在A1 B1单元格输入内容
  6. sheet['B1']= "次数"
  7. import pandas as pd                          #导入pandas库,读csv用的
  8. pd = pd.read_csv('002.csv',encoding='utf-8')      #打开csv文件,读取内容

  9. alllist = '、'.join(pd['参与人员'])              #用顿号拼接人员一列
  10. wordlist = list(alllist.split('、'))             #转成列表格式,以顿号为识别分割符
  11. print(wordlist)                                     #打印列表格式
  12. wordset = set(wordlist)                            #去掉重复内容


  13. newlist = []                                            #创建空列表来存储姓名和次数
  14. for word in wordset:
  15.     freq = wordlist.count(word)                               #计算出现次数
  16.     sheet.append([word,freq])                                   #把内容添加到sheet
  17.     newlist.append([word,freq])                                #把内容加入空列表


  18. newlist = sorted(newlist,key=lambda k:k[1],reverse=True)  #给列表排序
  19. wb.save( "测试3.xlsx")
  20. print(newlist)
复制代码



回复

使用道具 举报

497

主题

7万

元宝

78万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
784980
 楼主| 发表于 2021-10-2 20:55:25 | 显示全部楼层
最新积分细则代码,目前处于测试阶段
  1. # 导入excel模块,
  2. from openpyxl import Workbook                         #导入Excel模块
  3. wb = Workbook()                                  #创建一个Excel文件
  4. sheet = wb.active                                  #获取当前sheet名称
  5. sheet.title = "斑马救援积分明细"                          #修改sheet名称
  6. sheet['A1']= "姓名"                                    #在A1 B1单元格输入内容
  7. sheet['B1']= "分数"

  8. # 导入pandas库,读取表格
  9. import pandas as pd
  10. #pd = pd.read_csv('002.csv',encoding='utf-8')      #打开csv文件,读取内容
  11. pd = pd.read_excel('002.xlsx')                    #打开excel文件,读取内容
  12. #分别拿出参与人员和出勤类型数据,为创建元组做准备
  13. alllist = ','.join(pd['参与人员'])              #用逗号拼接人员一列,此处生成不是列表,是字符串
  14. alllist = list(alllist.split(','))             #把上一步的字符串转成列表格式,以逗号为识别分割符
  15. classlist = '、'.join(pd['出勤类型'])        #拼接出勤类型成字符串
  16. classlist = list(classlist.split('、'))    #把拼接出来的字符串转成列表

  17. dalist = []                 #创建一个空列表存放所有的姓名(重复姓名都在这里边)
  18. b = []                      #创建空列表存放去重后的姓名
  19. # 创建元组,让出勤类型和出勤人员一一对应
  20. zidian = zip(classlist,alllist)
  21. # 循环元组内容,判断哪种类型应该积分多少
  22. for i in list(zidian):
  23.     if i[0] == '第一类1分':
  24.         dalist.append(i[1].split('、'))
  25.     elif i[0] == '第二类2分':
  26.         dalist.append(i[1].split('、')*2)
  27.     elif i[0] == '第三类3分':
  28.         dalist.append(i[1].split('、')*3)

  29. #这一步,把大列表里面嵌套的小列表,全部清空,只把姓名拿出来放到一个列表b里
  30. for a in dalist:
  31.     b.extend(a)

  32. name = set(b)     #人员去重,每个名字只留下一个

  33. newlist = []                                            #创建空列表来存储姓名和次数
  34. for word in name:
  35.     freq = b.count(word)                               #计算出现次数
  36.     sheet.append([word,freq])                                   #把内容添加到sheet
  37.     newlist.append([word,freq])                                #把内容加入空列表


  38. newlist = sorted(newlist,key=lambda k:k[1],reverse=True)  #给列表排序
  39. wb.save( "积分明细.xlsx")
  40. print(newlist)
复制代码




回复

使用道具 举报

497

主题

7万

元宝

78万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
784980
 楼主| 发表于 2021-10-5 14:06:15 | 显示全部楼层
相比于楼上,增加了excel行数的读取,和处理数据的计算,通过对比两个数字,来判断是否全部数据都处理完。
  1. # 导入openpy模块,操作最后一步导出excel
  2. from openpyxl import Workbook                         #导入Excel模块
  3. wb = Workbook()                                  #创建一个Excel文件
  4. sheet = wb.active                                  #获取当前sheet名称
  5. sheet.title = "斑马救援积分明细"                          #修改sheet名称
  6. sheet['A1']= "姓名"                                    #在A1 B1单元格输入内容
  7. sheet['B1']= "分数"

  8. # 导入pandas库,读取表格
  9. import pandas as pd
  10. #pd = pd.read_csv('002.csv',encoding='utf-8')      #打开csv文件,读取内容
  11. pd = pd.read_excel('全部记录.xlsx')                    #打开excel文件,读取内容
  12. linesnum = pd.index.stop                 #excel数据行数
  13. #分别拿出参与人员和出勤类型数据,为创建元组做准备
  14. alllist = ','.join(pd['参与人员'])              #用逗号拼接人员一列,此处生成不是列表,是字符串
  15. alllist = list(alllist.split(','))             #把上一步的字符串转成列表格式,以逗号为识别分割符
  16. classlist = '、'.join(pd['积分类型'])        #拼接出勤类型成字符串
  17. classlist = list(classlist.split('、'))    #把拼接出来的字符串转成列表
  18. x = 0                             #储存处理数据的数目
  19. dalist = []                 #创建一个空列表存放所有的姓名(重复姓名都在这里边)
  20. b = []                      #创建空列表存放去重后的姓名
  21. # 创建元组,让出勤类型和出勤人员一一对应
  22. zidian = zip(classlist,alllist)
  23. # 循环元组内容,判断哪种类型应该积分多少
  24. for i in list(zidian):
  25.     if i[0] == '1分':
  26.         dalist.append(i[1].split('、'))
  27.         x = x + 1
  28.     elif i[0] == '2分':
  29.         dalist.append(i[1].split('、')*2)
  30.         x = x + 1
  31.     elif i[0] == '3分':
  32.         dalist.append(i[1].split('、')*3)
  33.         x = x + 1
  34.     else:
  35.         print(f'积分类型为{i[0]}的数据有问题')
  36. #这一步,把大列表里面嵌套的小列表,全部清空,只把姓名拿出来放到一个列表b里
  37. for a in dalist:
  38.     b.extend(a)

  39. name = set(b)     #人员去重,每个名字只留下一个

  40. newlist = []                                            #创建空列表来存储姓名和次数
  41. for word in name:
  42.     freq = b.count(word)                               #计算出现次数
  43.     sheet.append([word,freq])                                   #把内容添加到sheet
  44.     newlist.append([word,freq])                                #把内容加入空列表


  45. newlist = sorted(newlist,key=lambda k:k[1],reverse=True)  #给列表排序

  46. #用excel行数对比处理的数据,如果一样就说明全部数据已经处理完,如果不同,就说明有的数据没有处理
  47. if linesnum == x:
  48.     print(f'数据处理完毕,共{linesnum}条记录')
  49.     print(newlist)
  50.     wb.save("积分明细.xlsx")
  51. else:
  52.     print(f'共有数据{linesnum},已经处理{x}条,请排查数据')
复制代码
回复

使用道具 举报

497

主题

7万

元宝

78万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
784980
 楼主| 发表于 昨天 15:46 | 显示全部楼层
AI 写的不带积分版本的,好用,先收藏
  1. import csv
  2. from collections import defaultdict


  3. def count_names(csv_file):
  4.     # 创建一个默认值为0的字典来存储姓名计数
  5.     name_counts = defaultdict(int)

  6.     with open(csv_file, mode='r', encoding='gbk') as file:
  7.         reader = csv.DictReader(file)

  8.         # 检查"人员"列是否存在
  9.         if '人员' not in reader.fieldnames:
  10.             print(f"错误:CSV文件中没有名为'人员'的列")
  11.             return None

  12.         for row in reader:
  13.             # 获取"人员"列的内容
  14.             names_str = row['人员'].strip()

  15.             # 如果单元格为空,跳过
  16.             if not names_str:
  17.                 continue

  18.             # 用顿号分隔姓名
  19.             names = [name.strip() for name in names_str.split('、') if name.strip()]

  20.             # 统计每个姓名
  21.             for name in names:
  22.                 name_counts[name] += 1

  23.     return dict(name_counts)


  24. # 使用示例
  25. csv_path = '睢县斑马救援记录.csv'  # 替换为你的CSV文件路径
  26. result = count_names(csv_path)

  27. if result:
  28.     # 按出现次数降序排序并打印结果
  29.     sorted_counts = sorted(result.items(), key=lambda x: x[1], reverse=True)

  30.     print("姓名统计结果:")
  31.     print("------------------")
  32.     print("{:<15} {:<10}".format("姓名", "出现次数"))
  33.     for name, count in sorted_counts:
  34.         print("{:<15} {:<10}".format(name, count))

  35. if result:
  36.     # 保存结果到新的CSV文件
  37.     with open('name_counts.csv', mode='w', encoding='utf-8', newline='') as out_file:
  38.         writer = csv.writer(out_file)
  39.         writer.writerow(['姓名', '出现次数'])
  40.         for name, count in sorted(result.items(), key=lambda x: x[1], reverse=True):
  41.             writer.writerow([name, count])
  42.     print("\n结果已保存到name_counts.csv")
复制代码




回复

使用道具 举报

497

主题

7万

元宝

78万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
784980
 楼主| 发表于 昨天 15:53 | 显示全部楼层
加上时间段的
  1. import csv
  2. from collections import defaultdict
  3. from datetime import datetime

  4. def count_names_with_date_filter(csv_file, date_column, start_date=None, end_date=None, encoding='gbk'):
  5.     """
  6.     统计姓名出现次数,并按日期范围筛选
  7.    
  8.     参数:
  9.         csv_file: CSV文件路径
  10.         date_column: 日期列的列名
  11.         start_date: 开始日期(字符串,格式'YYYY-MM-DD')
  12.         end_date: 结束日期(字符串,格式'YYYY-MM-DD')
  13.         encoding: 文件编码
  14.         
  15.     返回:
  16.         姓名计数字典
  17.     """
  18.     name_counts = defaultdict(int)
  19.    
  20.     # 转换日期字符串为datetime对象
  21.     start_dt = datetime.strptime(start_date, '%Y-%m-%d') if start_date else None
  22.     end_dt = datetime.strptime(end_date, '%Y-%m-%d') if end_date else None
  23.    
  24.     try:
  25.         with open(csv_file, mode='r', encoding=encoding) as file:
  26.             reader = csv.DictReader(file)
  27.             
  28.             # 检查必要的列是否存在
  29.             required_columns = ['人员', date_column]
  30.             missing_columns = [col for col in required_columns if col not in reader.fieldnames]
  31.             
  32.             if missing_columns:
  33.                 print(f"错误:CSV文件中缺少必要的列: {missing_columns}")
  34.                 print(f"可用的列有:{reader.fieldnames}")
  35.                 return None
  36.             
  37.             for row in reader:
  38.                 # 处理日期
  39.                 date_str = row[date_column].strip()
  40.                 if not date_str:
  41.                     continue
  42.                     
  43.                 try:
  44.                     row_date = datetime.strptime(date_str, '%Y-%m-%d')
  45.                 except ValueError:
  46.                     # 尝试其他常见日期格式
  47.                     for fmt in ('%Y/%m/%d', '%Y年%m月%d日', '%Y.%m.%d'):
  48.                         try:
  49.                             row_date = datetime.strptime(date_str, fmt)
  50.                             break
  51.                         except ValueError:
  52.                             continue
  53.                     else:
  54.                         # 所有格式都解析失败,跳过这行
  55.                         continue
  56.                
  57.                 # 日期范围筛选
  58.                 if start_dt and row_date < start_dt:
  59.                     continue
  60.                 if end_dt and row_date > end_dt:
  61.                     continue
  62.                
  63.                 # 处理姓名
  64.                 names_str = row['人员'].strip()
  65.                 if not names_str:
  66.                     continue
  67.                     
  68.                 # 使用顿号分隔姓名
  69.                 names = [name.strip() for name in names_str.replace('、', '、').split('、') if name.strip()]
  70.                
  71.                 for name in names:
  72.                     name_counts[name] += 1
  73.    
  74.     except UnicodeDecodeError:
  75.         # 如果当前编码失败,尝试utf-8-sig
  76.         print(f"使用{encoding}编码失败,尝试utf-8-sig...")
  77.         return count_names_with_date_filter(csv_file, date_column, start_date, end_date, 'utf-8-sig')
  78.    
  79.     return dict(name_counts)

  80. # 使用示例
  81. csv_path = 'your_file.csv'  # 替换为你的CSV文件路径
  82. date_column = '日期'  # 替换为你的日期列的列名

  83. # 设置日期范围(可选)
  84. start_date = '2023-01-01'  # 格式为'YYYY-MM-DD'
  85. end_date = '2023-12-31'    # 格式为'YYYY-MM-DD'

  86. result = count_names_with_date_filter(
  87.     csv_path,
  88.     date_column,
  89.     start_date=start_date,
  90.     end_date=end_date
  91. )

  92. if result:
  93.     sorted_counts = sorted(result.items(), key=lambda x: x[1], reverse=True)
  94.    
  95.     print(f"姓名统计结果 (日期范围: {start_date or '最早'} 至 {end_date or '最新'}):")
  96.     print("------------------")
  97.     print("{:<15} {:<10}".format("姓名", "出现次数"))
  98.     for name, count in sorted_counts:
  99.         print("{:<15} {:<10}".format(name, count))
  100.    
  101.     # 可选:保存结果到CSV
  102.     # with open('name_counts_result.csv', 'w', encoding='utf-8-sig', newline='') as f:
  103.     #     writer = csv.writer(f)
  104.     #     writer.writerow(['姓名', '出现次数'])
  105.     #     writer.writerows(sorted_counts)
复制代码




回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|五花八门论坛 ( 豫ICP备15031300号-3 )

GMT+8, 2025-12-19 00:06 , Processed in 0.049901 second(s), 18 queries .

本站已稳定运营:

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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