pandas通过充电订单计算充电站场光伏发电时间利用率

一、案例背景

现有电动汽车充电站订单记录数据集,包含很多站场很多天的数据,数据截取了早上6点至晚上19点的数据,字段包括充电站名称,充电桩名称,充电枪名称,开始充电时间,结束充电时间。充电站里面很多充电枪,雨棚上搭建了光伏发电,光伏发的电全部用于汽车充电,充电站里只要有大于1条枪充电,充电期间光伏发的电都会被使用。当所有枪都没有充电时,光伏发的电将被浪费掉。通过这些数据计算每个充电站场每天有人充电时间占比,即光伏时间利用率。示例数据:假设场站有两条枪,A枪和B枪,在某一天这些枪有下面的充电订单:

充电枪开始充电时间结束充电时间
A枪2023-10-21 11:32:222023-10-21 12:22:20
B枪2023-10-21 11:45:252023-10-21 13:15:24
A枪2023-10-21 13:50:212023-10-21 14:30:21

以上三条计算实际的光伏利用时间段为【2023-10-21 11:32:22,2023-10-21 13:15:24】、【2023-10-21 13:50:21,2023-10-21 14:30:21】。最终计算这些光伏利用时间段占一天中的百分比。

二、解题思路

1、将开始充电时间和结束充电时间转换为在一天当中第几秒。比如开始时间为2023-10-21 10:01:21转换为10*60*60+1*60+21=36081,即这个时间是在当天的36081秒。全天共60*60*25=86400秒。


1、日期转换
'''
datetime.strptime(start_time,"%Y-%m-%d %H:%M:%S"): 这一行将start_time字符串解析为一个datetime对象。%Y-%m-%d %H:%M:%S是Python的日期和时间格式,其中:

%Y 表示四位数的年份 (例如, 2023)
%m 表示两位数的月份 (例如, 07)
%d 表示两位数的日期 (例如, 06)
%H 表示24小时制的小时数 (例如, 13)
%M 表示分钟数 (例如, 30)
%S 表示秒数 (例如, 45)
'''
t1=datetime.strptime(start_time,"%Y-%m-%d %H:%M:%S") #2023-10-21 11:55:23

2、日期拼接
t2=datetime.combine(t1.date(),datetime.min.time()) #2023-10-21 00:00:00

3、计算秒数
'''
这行代码计算了两个datetime对象之间的差值,得到的结果是一个timedelta对象,该对象包含了两个时间点之间的时间差。这个差值是以秒为单位的。
'''
total_seconds=int((t1-t2).total_seconds()) #total_seconds()方法返回总秒数

2、编写函数,接受一个时间间隔列表作为输入,并返回一个合并后的时间间隔列表。这在日程安排或时间段合并等应用中可能会有用。

#输入[[3,7],[2,6],[4,5],[12,19]]输出[[2,7],[12,19]]
def merge_time_intervals(intervals):
    if not intervals:
        return []

    # 根据时间区间的起始时间进行排序
    intervals.sort(key=lambda x: x[0])

    merged = [intervals[0]]
    for interval in intervals[1:]:
        if interval[0] <= merged[-1][1]:
            print("merged[-1][1]:",merged[-1][1])
            merged[-1][1] = max(merged[-1][1], interval[1])
        else:
            merged.append(interval)
    return merged

input=[[3,7],[2,6],[4,5],[12,19]]
print(merge_time_intervals(input))

3、计算合并后的时间间隔列表的总秒数

#计算时间间隔列表merged里面的总秒数
#输入[[3,7],[2,6],[4,5],[12,19]]输出[[2,7],[12,19]]

def merge_time_intervals(intervals):
    if not intervals:
        return []

    # 根据时间区间的起始时间进行排序
    intervals.sort(key=lambda x: x[0])

    merged = [intervals[0]]
    for interval in intervals[1:]:
        if interval[0] <= merged[-1][1]:
            #print("merged[-1][1]:",merged[-1][1])
            merged[-1][1] = max(merged[-1][1], interval[1])
        else:
            merged.append(interval)
    print(merged)
    return merged

l=[[3,7],[2,6],[4,5],[12,19]]

merged=merge_time_intervals(l)


'''
merged 是一个元组列表[[2,7],[12,19]],每个元组包含两个元素,我们假设它们是时间戳。
列表中的元组表示一系列的时间段。
end - start 对每个元组中的 start 和 end 时间戳进行操作,得到每个时间段的持续时间。
sum(end - start for start, end in merged) 
使用了 Python 的生成器表达式(也称为“列表推导式”)来生成一个包含所有时间差值的列表,
然后使用 sum() 函数计算这个列表中所有值的总和。
'''
total_duration = sum(end - start for start, end in merged)
print(total_duration)

#输出:[[2, 7], [12, 19]]
#      12

#(7-2) + (19-12)  =5+7=12

三、完整代码


import pandas as pd
from datetime import datetime
df = pd.read_excel(r'E:\SynologyDrive\python\计算光伏时间利用率\用于光伏利用率计算的数据集-发csdn.xlsx')

grouped = df.groupby(['场站名称',df['开始充电时间'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S').date())])
# 计算开始时间和结束时间在一天当中第几秒  
def get_time_difference(start_time, end_time):  
    #start_time=2023-08-26 10:11:32  
    r1=int((datetime.strptime(start_time,"%Y-%m-%d %H:%M:%S") - datetime.combine(datetime.strptime(start_time,"%Y-%m-%d %H:%M:%S").date(),datetime.min.time())).total_seconds())

    if datetime.strptime(start_time,"%Y-%m-%d %H:%M:%S").date()<datetime.strptime(end_time,"%Y-%m-%d %H:%M:%S").date():
        r2=86400 #开始时间的日期小于结束时间的日期,即充电订单时间跨了一天
    else:
        r2=int((datetime.strptime(end_time,"%Y-%m-%d %H:%M:%S") - datetime.combine(datetime.strptime(end_time,"%Y-%m-%d %H:%M:%S").date(),datetime.min.time())).total_seconds())
    #print(r1,r2)
    return [r1,r2]

# 对每个分组中的开始时间和结束时间放到一个列表中  
result = {  
    '场站名称': [],  
    '日期': [],  
    '开始时间': [],  
    '结束时间': [],
    '填充区间':[],
    '合并区间':[],
    '时长':[],
    '光伏时间利用率':[]
}  

#输入[[3,7],[2,6],[4,5],[12,19]]输出[[2,7],[12,19]]
def merge_time_intervals(intervals):
    if not intervals:
        return []

    # 根据时间区间的起始时间进行排序
    intervals.sort(key=lambda x: x[0])

    merged = [intervals[0]]
    for interval in intervals[1:]:
        if interval[0] <= merged[-1][1]:
            #print("merged[-1][1]:",merged[-1][1])
            merged[-1][1] = max(merged[-1][1], interval[1])
        else:
            merged.append(interval)
    total_duration = sum(end - start for start, end in merged)
    时间利用率=total_duration/86400

    return merged,total_duration,时间利用率

for name, group in grouped:  
    result['场站名称'].append(name[0])  
    result['日期'].append(name[1])  
    result['开始时间'].append(group['开始充电时间'].tolist())  
    result['结束时间'].append(group['结束充电时间'].tolist())  
    r=[]
    for i,item in enumerate(group['开始充电时间'].tolist()):
        timerange=get_time_difference(group['开始充电时间'].tolist()[i],group['结束充电时间'].tolist()[i])
        r.append(timerange)

    result['填充区间'].append(r)
    t=merge_time_intervals(r)
    result['合并区间'].append(t[0])
    result['时长'].append(t[1])
    result['光伏时间利用率'].append(t[2])
  
# 打印结果  
for i, v in enumerate(result['场站名称']):  
    #print(f'场站名称: {v}, 日期: {result["日期"][i]}, 开始时间: {result["开始时间"][i]}, 结束时间: {result["结束时间"][i]},填充区间:{result["填充区间"][i]}')
    print(f'场站名称: {v}, 日期: {result["日期"][i]}, 合并区间:{result["合并区间"][i]},时长:{result["时长"][i]},光伏时间利用率:{result["光伏时间利用率"][i]}')

df = pd.DataFrame(result)  
  
# 将DataFrame写入Excel文件  
df.to_excel('光伏时间利用率计算结果result.xlsx', index=False)

四、相关数据集及计算结果

本文绑定两个资源:

1、数据集

2、计算结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值