数据介绍&分析目标
- 数据介绍
这里先简单描述一下数据集文件。这里有6个用户的用电数据。以1号用户为例,点进building1内会有meter1-meter20共20个Excel表格,其中meter1和meter2均为该家庭的用电总负荷,您可以选择其中之一作为该家庭的用电总负荷。
meter3~meter20分别代表该家庭的18种家用电器(每个编号对应的家电名称会通过另一张表保存)。 每条记录的时间间隔都在3-4秒左右
整个数据集结构如下图。每个csv文件中都只有两列内容统计时间、当前时间检测到的功率
分析目标
有了这些数据我们现在需要分析不同电器中每一天不同时间段段的使用频率。
那么一个电器的使用频率需要通过该电器的开关次数来定义。这里对于一次开关我们可以这样定义

数据分析
〇、导入需要的库
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import os
import re
import warnings
import seaborn as sns
import itertools
warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif']='SimHei'
plt.rcParams['axes.unicode_minus']=False
一、合并数据
读表获取每个房间的设备信息
- 只分析洗衣机、洗碗机、微波炉、电烤箱、电暖气、电炉、空调、空气处理装置
root=os.path.abspath("low_freq.csv")
users=os.listdir(root)
io = pd.io.excel.ExcelFile("新redd设备信息.xlsx")
devices_df={}
for i in range(1,7):
device=pd.read_excel(io, sheetname='房间'+str(i))
device=device[device["设备名称"].str.contains("洗衣机|洗碗机|微波炉|电烤箱|电暖气|电炉|空调|空气处理装置")]
name="building"+str(i)
devices_df[name]=device
io.close()
print('devices_df["building1"]示例数据结构如下:')
devices_df["building1"]
devices_df["building1"]示例数据结构如下:
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
|
设备号 |
设备名称 |
家电开启功率阈值/W |
家电关闭功率阈值/W |
开启的最短运行时间/s |
关闭的最短运行时间/s |
2 |
3 |
电烤箱 |
10.0 |
10.0 |
30.0 |
30.0 |
3 |
4 |
电烤箱 |
10.0 |
10.0 |
30.0 |
30.0 |
5 |
6 |
洗碗机 |
10.0 |
10.0 |
160.0 |
60.0 |
9 |
10 |
洗衣机 |
10.0 |
10.0 |
300.0 |
300.0 |
10 |
11 |
微波炉 |
10.0 |
10.0 |
15.0 |
30.0 |
13 |
14 |
电炉 |
10.0 |
10.0 |
30.0 |
30.0 |
19 |
20 |
洗衣机 |
10.0 |
10.0 |
300.0 |
300.0 |
合并所有表格
在原有基础上添加三列:
- 所属用户user
- 设备类型dev_type
- 开关状态 status
all_df=[]
for user in users:
print("\n==========正在合并%s的信息========="%user)
excels=os.path.join(root,os.path.join(user,"elec"))
file_path=os.path.join(root,excels)
for file in os.listdir(file_path):
the_type=int(re.findall("meter(.*).csv",file)[0])
if the_type not in list(devices_df[user]["设备号"]) or the_type==2:
continue
print(file,"正在合并meter",the_type)
excel=os.path.join(file_path,file)
df=pd.read_csv(excel)[1:]
length=len(df)
df["user"]=[user]*length
try:
df["dev_type"]=[devices_df[user].loc[devices_df[user]["设备号"]==the_type,"设备名称"].values[0]]*length
start_power=devices_df[user].loc[devices_df[user]["设备号"]==the_type,"家电开启功率阈值/W"].values[0]
df['status']=df['power'].apply(lambda x :1 if float(x)>10 else 0)
df['open_time']=[devices_df[user].loc[devices_df[user]["设备号"]==the_type,"开启的最短运行时间/s"].values[0]]*length
df['shut_time']=[devices_df[user].loc[devices_df[user]["设备号"]==the_type,"关闭的最短运行时间/s"].values[0]]*length
all_df.append(df)
except:
continue
print("合并所有building的信息...")
data=pd.concat(all_df)
data.head()
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
|
physical_quantity |
power |
user |
dev_type |
status |
open_time |
shut_time |
1 |
2011-04-18 09:22:13-04:00 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
2 |
2011-04-18 09:22:16-04:00 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
3 |
2011-04-18 09:22:20-04:00 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
4 |
2011-04-18 09:22:23-04:00 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
5 |
2011-04-18 09:22:26-04:00 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
二、数据清洗
1、physical_quantity重命名为time
2、由于time列的都以04:00结尾,由此去掉这一部分,并将该列转换为时间序列
3、将time时间序列设置为索引列
data.rename(columns={"physical_quantity":"time"},inplace=True)
data.time=data.time.str.replace("-04:00","")
data.time=pd.to_datetime(data.time)
data=data.set_index("time")
data.head()
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
|
power |
user |
dev_type |
status |
open_time |
shut_time |
time |
|
|
|
|
|
|
2011-04-18 09:22:13 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
2011-04-18 09:22:16 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
2011-04-18 09:22:20 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
2011-04-18 09:22:23 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
2011-04-18 09:22:26 |
0.0 |
building1 |
洗衣机 |
0 |
300.0 |
300.0 |
查看数据
data['power'].astype('float').plot(figsize=(12,8),title="用电功率天数统计")

开关状态判断
- 对于读取的状态数据(1为运行,0为关闭),将数据与最小开启/关闭时间作判断,更正误判状态
- 将状态值进行差分,差分结果0为运行,非0值统计为1,代表一次开关状态
def judge_status(data):
count=0
last=0
for k,v in itertools.groupby(data['status']):
sequence=len(list(v))
temp=data.iloc[last:count,]
if len(temp)==0:
continue
delta=(temp.index[-1]-temp.index[0]).seconds
if k==1:
if delta<temp['open_time'][0]:
data[count:sequence:,]=0
elif k==0:
if delta<temp['shut_time'][0]:
data[count:sequence:,]=1
count+=sequence
data['diff']=data['status'].diff().fillna(0)
data['diff']=data['diff'].apply(lambda x:1 if x!=0 else 0 )
三、用电时间段频率统计(时间序列聚合)
- 将所有用户时间汇总,聚合每半小时的数据,开关次数(记录条数)
- 汇总6张表(对应6个用户,每张表48条数据对应一天中的各个半小时)
result=[]
electrical=data.dev_type.unique()
for user in users:
for e in electrical:
print("\r正在计算{}:{}".format(user,e),end=" ")
half_data=data[(data["user"]==user) & (data["dev_type"]==e)]
if len(half_data)==0:
continue
judge_status(half_data)
hour_agg=half_data.resample("0.5H").sum()
user_names=[]
switches=[]
hours=[]
types=[]
for hour in range(48):
h=int(hour/2)
m=(hour%2*30)
temp=hour_agg[(hour_agg.index.hour==h) & (hour_agg.index.minute==m)]
switch=temp['diff'].sum()
switches.append(switch)
types.append(e)
user_names.append(user)
hours.append(hour)
add_df=pd.DataFrame({
"switch":switches,
"user":user_names,
"dev_type":types,
"hours":hours
})
result.append(add_df)
print("\n计算完成!")
正在计算building6:空气处理装置
计算完成!
1、结果可视化
res=pd.concat(result)
res.to_csv("result.csv",index=None)
plt.figure(figsize=(15,8))
total=res.groupby(["dev_type","hours"]).sum()
'''折线图'''
marker=['-.','+-','*-','p-','>-','X-','s-']
for e,m in zip(electrical,marker):
temp=total.loc[(e)]
plt.plot(temp.index,temp.switch,m,label=e)
x_major_locator=plt.MultipleLocator(1)
ax=plt.gca()
ax.xaxis.set_major_locator(x_major_locator)
plt.ylabel("开启总次数")
plt.xlabel("小时")
plt.legend()
plt.xlim(0,48)

'''柱状图'''
plt.figure(figsize=(15,8))
for e in electrical:
temp=total.loc[(e)]
plt.bar(temp.index,temp.switch,label=e)
x_major_locator=plt.MultipleLocator(1)
ax=plt.gca()
ax.xaxis.set_major_locator(x_major_locator)
plt.ylabel("开启总次数")
plt.xlabel("小时")
plt.legend()

2、统计每个用户一天中不同时间段的用电频率
user_df=res[res["dev_type"]!="总"]
users=list(user_df.user.unique())
frequency=[]
plt.figure(figsize=(24,10))
count=1
for user in users:
temp=user_df[user_df["user"]==user]
plt.subplot(2,3,count)
for d in list(temp.dev_type.unique()):
dev=temp[temp["dev_type"]==d]
total=dev['switch'].sum()
if total!=0:
dev['switch']/=total
plt.plot(dev.hours,dev.switch,label=d)
plt.title("{}电器各时间段使用频率".format(user))
plt.legend()
plt.xlabel("/半小时")
plt.ylabel("使用频率")
count+=1

数据集+源码获取