赵乾舟 发表于 2021-10-2 19:37:50

斑马救援出勤统计代码

内容来源于更早的一篇帖子 http://zhaoqianzhou.com/forum.php?mod=viewthread&tid=261&extra=page%3D6

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

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


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


newlist = sorted(newlist,key=lambda k:k,reverse=True)#给列表排序
wb.save( "测试3.xlsx")
print(newlist)


赵乾舟 发表于 2021-10-2 20:55:25

最新积分细则代码,目前处于测试阶段
# 导入excel模块,
from openpyxl import Workbook                         #导入Excel模块
wb = Workbook()                                  #创建一个Excel文件
sheet = wb.active                                  #获取当前sheet名称
sheet.title = "斑马救援积分明细"                        #修改sheet名称
sheet['A1']= "姓名"                                    #在A1 B1单元格输入内容
sheet['B1']= "分数"

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

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

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

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

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


newlist = sorted(newlist,key=lambda k:k,reverse=True)#给列表排序
wb.save( "积分明细.xlsx")
print(newlist)



赵乾舟 发表于 2021-10-5 14:06:15

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

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

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

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


newlist = sorted(newlist,key=lambda k:k,reverse=True)#给列表排序

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

赵乾舟 发表于 2025-12-18 15:46:40

AI 写的不带积分版本的,好用,先收藏
import csv
from collections import defaultdict


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

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

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

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

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

            # 用顿号分隔姓名
            names =

            # 统计每个姓名
            for name in names:
                name_counts += 1

    return dict(name_counts)


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

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

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

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




赵乾舟 发表于 2025-12-18 15:53:33

加上时间段的
import csv
from collections import defaultdict
from datetime import datetime

def count_names_with_date_filter(csv_file, date_column, start_date=None, end_date=None, encoding='gbk'):
    """
    统计姓名出现次数,并按日期范围筛选
   
    参数:
      csv_file: CSV文件路径
      date_column: 日期列的列名
      start_date: 开始日期(字符串,格式'YYYY-MM-DD')
      end_date: 结束日期(字符串,格式'YYYY-MM-DD')
      encoding: 文件编码
      
    返回:
      姓名计数字典
    """
    name_counts = defaultdict(int)
   
    # 转换日期字符串为datetime对象
    start_dt = datetime.strptime(start_date, '%Y-%m-%d') if start_date else None
    end_dt = datetime.strptime(end_date, '%Y-%m-%d') if end_date else None
   
    try:
      with open(csv_file, mode='r', encoding=encoding) as file:
            reader = csv.DictReader(file)
            
            # 检查必要的列是否存在
            required_columns = ['人员', date_column]
            missing_columns =
            
            if missing_columns:
                print(f"错误:CSV文件中缺少必要的列: {missing_columns}")
                print(f"可用的列有:{reader.fieldnames}")
                return None
            
            for row in reader:
                # 处理日期
                date_str = row.strip()
                if not date_str:
                  continue
                  
                try:
                  row_date = datetime.strptime(date_str, '%Y-%m-%d')
                except ValueError:
                  # 尝试其他常见日期格式
                  for fmt in ('%Y/%m/%d', '%Y年%m月%d日', '%Y.%m.%d'):
                        try:
                            row_date = datetime.strptime(date_str, fmt)
                            break
                        except ValueError:
                            continue
                  else:
                        # 所有格式都解析失败,跳过这行
                        continue
               
                # 日期范围筛选
                if start_dt and row_date < start_dt:
                  continue
                if end_dt and row_date > end_dt:
                  continue
               
                # 处理姓名
                names_str = row['人员'].strip()
                if not names_str:
                  continue
                  
                # 使用顿号分隔姓名
                names =
               
                for name in names:
                  name_counts += 1
   
    except UnicodeDecodeError:
      # 如果当前编码失败,尝试utf-8-sig
      print(f"使用{encoding}编码失败,尝试utf-8-sig...")
      return count_names_with_date_filter(csv_file, date_column, start_date, end_date, 'utf-8-sig')
   
    return dict(name_counts)

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

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

result = count_names_with_date_filter(
    csv_path,
    date_column,
    start_date=start_date,
    end_date=end_date
)

if result:
    sorted_counts = sorted(result.items(), key=lambda x: x, reverse=True)
   
    print(f"姓名统计结果 (日期范围: {start_date or '最早'} 至 {end_date or '最新'}):")
    print("------------------")
    print("{:<15} {:<10}".format("姓名", "出现次数"))
    for name, count in sorted_counts:
      print("{:<15} {:<10}".format(name, count))
   
    # 可选:保存结果到CSV
    # with open('name_counts_result.csv', 'w', encoding='utf-8-sig', newline='') as f:
    #   writer = csv.writer(f)
    #   writer.writerow(['姓名', '出现次数'])
    #   writer.writerows(sorted_counts)




页: [1]
查看完整版本: 斑马救援出勤统计代码