【数据分析】针对家庭用电数据进行时序分析(1)
0. 数据说明
本项目所用数据集包含了一个家庭6个月的用电数据,收集于2007年1月至2007年6月。
这些数据包括有功功率、无功功率、电压、电流强度、分项计量1(厨房)、分项计量2(洗衣房)和分项计量3(电热水器和空调)等信息。该数据集共有260,640个测量值,可以为了解家庭用电情况提供重要的见解。
我们要感谢databeats团队提供这个数据集。如果你在你的研究中使用这个数据集,请注明原作者:Georges Hébrail 和 Alice Bérard。
字段含义对照表:
列名 说明
Date 日期
Time 时间
Globalactivepower 除分项计量外所消耗的总有功功率(千瓦)
Globalreactivepower 该家庭消耗的总无功功率(千瓦)
Voltage 向家庭输送电力的电压(伏特)
Global_intensity 输送到家庭的平均电流强度(安培)
Submetering1 厨房消耗的有功功率(千瓦)
Submetering2 洗衣房所消耗的有功功率(千瓦)
Submetering3 电热水器和空调所消耗的有功功率(千瓦)
数据来源:
https://www.kaggle.com/datasets/thedevastator/240000-household-electricity-consumption-records
其他说明:
有功功率是保持用电设备正常运行所需的电功率,也就是将电能转换为其他形式能量(机械能、光能、热能)的电功率。比如:5.5千瓦的电动机就是把5.5千瓦的电能转换为机械能,带动水泵抽水或脱粒机脱粒;各种照明设备将电能转换为光能,供人们生活和工作照明。无功功率比较抽象,它是用于电路内电场与磁场的交换,并用来在电气设备中建立和维持磁场的电功率。它不对外作功,而是转变为其他形式的能量。凡是有电磁线圈的电气设备,要建立磁场,就要消耗无功功率。比如40瓦的日光灯,除需40多瓦有功功率(镇流器也需消耗一部分有功功率)来发光外,还需80乏左右的无功功率供镇流器的线圈建立交变磁场用。由于它不对外做功,才被称之为“无功”。
1. 前期工作
1.1 导包
import numpy as np
import pandas as pd
from pyecharts.charts import *
import pyecharts.options as opts
from statsmodels.tsa.seasonal import seasonal_decompose
import matplotlib.pyplot as plt
# plt.rcParams['axes.unicode_minus']=False
# plt.rcParams['font.sans-serif'] = ['SimHei']```
1.2 读取数据
# 数据路径
data_path = r'/home/mw/input/Household_Electricity4767/household_power_consumption.csv'
# 读取数据
df = pd.read_csv(data_path,index_col='index')
# 预览数据
df.head()
输出结果:
index | Date | Time | Global_active_power | Global_reactive_power | Voltage | Global_intensity | Sub_metering_1 | Sub_metering_2 | Sub_metering_3 |
---|---|---|---|---|---|---|---|---|---|
0 | 16/12/2006 | 17:24:00 | 4.216 | 0.418 | 234.840 | 18.400 | 0.000 | 1.000 | 17.000 |
1 | 16/12/2006 | 17:25:00 | 5.360 | 0.436 | 233.630 | 23.000 | 0.000 | 1.000 | 16.000 |
2 | 16/12/2006 | 17:26:00 | 5.374 | 0.498 | 233.290 | 23.000 | 0.000 | 2.000 | 17.000 |
3 | 16/12/2006 | 17:27:00 | 5.388 | 0.502 | 233.740 | 23.000 | 0.000 | 1.000 | 17.000 |
4 | 16/12/2006 | 17:28:00 | 3.666 | 0.528 | 235.680 | 15.800 | 0.000 | 1.000 | 17.000 |
2. 数据处理
2.1 数据预览
# 将列名替换为中文
df.rename(columns={
'Date': '日期',
'Time': '时间',
'Global_active_power': '有功功率',
'Global_reactive_power': '无功功率',
'Voltage': '电压',
'Global_intensity': '电流',
'Sub_metering_1': '厨房的有功功率',
'Sub_metering_2': '洗衣房的有功功率',
'Sub_metering_3': '电热水器和空调的有功功率',
},inplace=1)
# 再次预览前5行数据
df.head() # 列名改成中文顺眼多了
输出结果:
日期 | 时间 | 有功功率 | 无功功率 | 电压 | 电流 | 厨房的有功功率 | 洗衣房的有功功率 | 电热水器和空调的有功功率 |
---|---|---|---|---|---|---|---|---|
16/12/2006 | 17:24:00 | 4.216 | 0.418 | 234.84 | 18.4 | 0.0 | 1.0 | 17.0 |
16/12/2006 | 17:25:00 | 5.36 | 0.436 | 233.63 | 23.0 | 0.0 | 1.0 | 16.0 |
16/12/2006 | 17:26:00 | 5.374 | 0.498 | 233.29 | 23.0 | 0.0 | 2.0 | 17.0 |
16/12/2006 | 17:27:00 | 5.388 | 0.502 | 233.74 | 23.0 | 0.0 | 1.0 | 17.0 |
16/12/2006 | 17:28:00 | 3.666 | 0.528 | 235.68 | 15.8 | 0.0 | 1.0 | 17.0 |
解惑:
0、为什么这样导包?
a:这样导包的主要原因是为了方便使用这些库中的函数和类。具体来说:
- `import numpy as np`:将`numpy`库导入,并将其命名为`np`,这样我们在调用`numpy`库中的函数或类时,可以使用`np`作为前缀,比如`np.array()`。
- `import pandas as pd`:将`pandas`库导入,并将其命名为`pd`,这样我们在调用`pandas`库中的函数或类时,可以使用`pd`作为前缀,比如`pd.DataFrame()`。
- `from pyecharts.charts import *`:从`pyecharts.charts`模块中导入所有的类和函数,这样我们在调用`pyecharts`库中的函数或类时,可以直接使用其名称,比如`Line()`。
- `import pyecharts.options as opts`:将`pyecharts.options`模块导入,并将其命名为`opts`,这样我们在调用`pyecharts`库中的选项时,可以使用`opts`作为前缀,比如`opts.Title()`。
- `from statsmodels.tsa.seasonal import seasonal_decompose`:从`statsmodels.tsa.seasonal`模块中导入`seasonal_decompose`函数,这样我们在调用该函数时,可以直接使用其名称。
- `import matplotlib.pyplot as plt`:将`matplotlib.pyplot`模块导入,并将其命名为`plt`,这样我们在调用`matplotlib`库中的函数或类时,可以使用`plt`作为前缀,比如`plt.plot()`。
- `plt.rcParams['axes.unicode_minus']=False`和`plt.rcParams['font.sans-serif'] = ['SimHei']`:这两行代码是为了设置`matplotlib`库的显示参数,使得中文可以正常显示,并且减少负号显示的问题。
1、pyecharts.options这个模块是做什么的?
a:pyecharts.options
模块是pyecharts
库中的一个子模块,主要用于定义可视化图形的各种选项参数,例如图形的标题、坐标轴的标签、图例的样式等等。pyecharts
库是一个基于echarts
库的Python可视化库,提供了多种类型的可视化图表,包括柱状图、折线图、散点图、地图等等,pyecharts.options
模块的作用就是为这些图表提供各种选项参数,以便用户可以根据自己的需求来自定义图表的外观和样式。例如,可以使用opts.Title()
函数来设置图表的标题,使用opts.Legend()
函数来设置图例的样式,使用opts.Toolbox()
函数来添加工具栏等等。这些选项参数可以通过链式调用来设置,例如:
from pyecharts.charts import Bar
import pyecharts.options as opts
bar = Bar()
bar.add_xaxis(["A", "B", "C", "D", "E"])
bar.add_yaxis("Series", [10, 20, 30, 40, 50])
bar.set_global_opts(title_opts=opts.Title(text="Bar Chart", subtext="Example"),
legend_opts=opts.Legend(pos_right="10%"),
toolbox_opts=opts.Toolbox())
bar.render("bar.html")
上面的代码中,我们使用opts.Title()
函数设置了图表的标题,使用opts.Legend()
函数设置了图例的位置,使用opts.Toolbox()
函数添加了工具栏,并将这些选项参数传递给set_global_opts()
方法来设置全局选项。
2、pyecharts.charts呢?
a:pyecharts.charts
模块是pyecharts
库中的一个子模块,主要用于创建各种类型的可视化图表,例如柱状图、折线图、散点图、地图等等。pyecharts
库是一个基于echarts
库的Python可视化库,提供了多种类型的可视化图表,pyecharts.charts
模块的作用就是为这些图表提供各种方法和属性,以便用户可以根据自己的需求来创建和自定义图表。例如,可以使用Line()
函数创建一个折线图,然后使用add_xaxis()
函数和add_yaxis()
函数来添加数据,最后使用set_global_opts()
函数来设置图表的全局选项,如下所示:
from pyecharts.charts import Line
import pyecharts.options as opts
line = Line()
line.add_xaxis(["A", "B", "C", "D", "E"])
line.add_yaxis("Series", [10, 20, 30, 40, 50])
line.set_global_opts(title_opts=opts.Title(text="Line Chart", subtext="Example"),
legend_opts=opts.Legend(pos_right="10%"))
line.render("line.html")
上面的代码中,我们使用Line()
函数创建了一个折线图,使用add_xaxis()
函数和add_yaxis()
函数添加了数据,使用set_global_opts()
函数设置了图表的标题和图例位置,并将这些选项参数传递给set_global_opts()
方法来设置全局选项。最后,使用render()
函数将图表渲染成HTML文件。
3、from statsmodels.tsa.seasonal import seasonal_decompose呢?
a:from statsmodels.tsa.seasonal import seasonal_decompose
这行代码是从statsmodels.tsa.seasonal
模块中导入了seasonal_decompose
函数。statsmodels
是一个Python库,提供了各种统计模型和方法,包括时间序列分析、回归分析、统计模型检验等等。tsa
是time series analysis
的缩写,表示时间序列分析,其中seasonal
表示季节性分析,seasonal_decompose
函数用于对季节性时间序列进行分解,将其分解为趋势、季节和残差三个部分。这个函数的主要作用是帮助用户了解时间序列数据的季节性变化趋势,从而更好地进行数据分析和预测。在使用该函数时,需要将时间序列数据作为函数的参数传递进去,并指定季节周期的长度。例如:
from statsmodels.tsa.seasonal import seasonal_decompose
import pandas as pd
# 创建一个季节性时间序列
data = pd.DataFrame({'date': pd.date_range(start='2022-01-01', end='2022-12-31', freq='D'),
'value': [i % 7 + 1 for i in range(365)]})
# 对时间序列进行季节性分解
result = seasonal_decompose(data['value'], model='additive', period=7)
# 输出分解结果
print(result.trend)
print(result.seasonal)
print(result.resid)
print(result.observed)
上面的代码中,我们首先创建了一个季节性时间序列,然后使用seasonal_decompose()
函数对其进行季节性分解,其中model
参数指定了分解模型,可以是additive
或multiplicative
,period
参数指定了季节周期的长度,这里我们指定为7,表示一周的周期。最后,我们输出了分解结果中的趋势、季节和残差三个部分,以及原始数据。
4、import matplotlib.pyplot as plt这个呢?
a:import matplotlib.pyplot as plt
是将matplotlib.pyplot
模块导入,并将其命名为plt
,这样我们在调用matplotlib
库中的函数或类时,可以使用plt
作为前缀,比如plt.plot()
。matplotlib
是一个Python绘图库,提供了各种类型的图表,包括线性图、散点图、柱状图、饼图等等,pyplot
是matplotlib
库中的一个子模块,提供了一些方便的函数和工具,可以帮助用户更方便地进行图表绘制和数据可视化。例如,可以使用plot()
函数来绘制线性图,使用scatter()
函数来绘制散点图,使用bar()
函数来绘制柱状图等等。以下是一个简单的例子:
import matplotlib.pyplot as plt
# 创建数据
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40, 50]
# 绘制线性图
plt.plot(x, y)
# 添加标题和坐标轴标签
plt.title("Line Chart")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
# 显示图表
plt.show()
上面的代码中,我们首先创建了一个包含5个数据点的线性数据,然后使用plot()
函数绘制了这些数据的线性图,使用title()
函数、xlabel()
函数和ylabel()
函数添加了标题和坐标轴标签,最后使用show()
函数显示图表。
5、df = pd.read_csv(data_path,index_col='index'),index_col是什么?
a:index_col
是pandas.read_csv()
函数中的一个参数,用于指定将哪一列作为数据的索引(行标签)。默认情况下,read_csv()
函数会自动为数据生成一个整数索引,但是在某些情况下,我们可能需要将某一列作为数据的索引,这时就可以使用index_col
参数。例如,如果我们有一个包含日期和数值的CSV文件,想要将日期作为数据的索引,可以使用以下代码:
import pandas as pd
data_path = 'data.csv'
df = pd.read_csv(data_path, index_col='date')
在上面的代码中,我们使用read_csv()
函数读取了一个CSV文件,并将其中的date
列作为数据的索引。这样,我们就可以通过日期来索引和操作数据了。如果不指定index_col
参数,则默认使用第一列作为数据的索引。
6、索引是用来干嘛的,为什么要指定?
a:索引是用来标识和访问数据的标签或键,它可以帮助我们更方便地对数据进行操作和分析。在pandas
库中,索引分为行索引和列索引两种。行索引用于标识和访问数据行,列索引用于标识和访问数据列。
在pandas
中,数据的索引可以由用户指定,也可以由系统自动生成。如果数据没有指定索引,则默认使用从0开始的整数索引。但是,在某些情况下,我们可能需要根据数据的特性或需求来指定索引,例如,如果数据中包含日期或时间等信息,我们可以将其作为索引,便于按时间序列进行分析和操作;如果数据中有某一列唯一标识每个数据项,则可以将其作为索引,便于按照该列进行数据查找和聚合。
指定索引可以让我们更方便地访问和操作数据,例如,可以通过索引来选择特定的行或列,可以通过索引来对数据进行排序、切片、分组和聚合等操作。因此,在读取数据时,根据数据的特性和需求来指定索引是一个很好的选择。
7、rcParams
plt.rcParams['axes.unicode_minus']=False
plt.rcParams['font.sans-serif'] = ['SimHei']:
这两行代码是为了设置matplotlib库的显示参数,使得中文可以正常显示,并且减少负号显示的问题。
8、inplace = 1什么意思?
a:inplace
是pandas
库中很多方法的一个可选参数,用于指示是否将修改应用到原DataFrame中。如果inplace=True
,则会直接在原DataFrame上进行修改,并返回None
;如果inplace=False
(默认值),则会返回一个新的DataFrame,原DataFrame不会改变。
使用inplace=True
可以提高代码的效率,避免在内存中创建新的对象,特别是当数据集很大时。但是,需要注意的是,这样会直接修改原始数据,可能会影响到后续的操作。因此,在使用inplace
参数时,需要谨慎考虑是否需要在原始数据上进行修改。
在上面的代码中,使用了inplace=1
,这相当于inplace=True
,表示直接在原DataFrame上进行修改。