【資料分析】針對家庭用電資料進行時序分析(1)

白豬有妖氣發表於2023-09-26

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庫,提供了各種統計模型和方法,包括時間序列分析、迴歸分析、統計模型檢驗等等。tsatime 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引數指定了分解模型,可以是additivemultiplicativeperiod引數指定了季節週期的長度,這裡我們指定為7,表示一週的週期。最後,我們輸出了分解結果中的趨勢、季節和殘差三個部分,以及原始資料。
4、import matplotlib.pyplot as plt這個呢?
a:import matplotlib.pyplot as plt是將matplotlib.pyplot模組匯入,並將其命名為plt,這樣我們在呼叫matplotlib庫中的函式或類時,可以使用plt作為字首,比如plt.plot()matplotlib是一個Python繪相簿,提供了各種型別的圖表,包括線性圖、散點圖、柱狀圖、餅圖等等,pyplotmatplotlib庫中的一個子模組,提供了一些方便的函式和工具,可以幫助使用者更方便地進行圖表繪製和資料視覺化。例如,可以使用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_colpandas.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:inplacepandas庫中很多方法的一個可選引數,用於指示是否將修改應用到原DataFrame中。如果inplace=True,則會直接在原DataFrame上進行修改,並返回None;如果inplace=False(預設值),則會返回一個新的DataFrame,原DataFrame不會改變。

使用inplace=True可以提高程式碼的效率,避免在記憶體中建立新的物件,特別是當資料集很大時。但是,需要注意的是,這樣會直接修改原始資料,可能會影響到後續的操作。因此,在使用inplace引數時,需要謹慎考慮是否需要在原始資料上進行修改。

在上面的程式碼中,使用了inplace=1,這相當於inplace=True,表示直接在原DataFrame上進行修改。

相關文章