แสดงกราฟข้อมูลจากไฟล์ .csv โดยการใช้ Jupyter และ Pandas

หลังจากที่เรา การติดตั้ง VirtualEnv สำหรับการแยก Python Environment และ ทำ Data Logger ด้วย TTGo T1 (ESP32) และโมดูล DS3231 กันไปแล้ว วันนี้เราจึงมีไฟล์ .csv มาให้เล่นกันในวันนี้แล้วครับ! วันนี้เราจะใช้ Pandas และ Jupyter Lab เข้ามาช่วยเขียนโค๊ดกันนะครับ

Pandas & Jupyter Lab

Pandas เป็น Python Library ที่เอาไว้ช่วยทำ Data Analysis ครับ ทำได้ทั้งปรับปรุง เปลี่ยนแปลง เพิ่ม/ลด หรือแม้กระทั่ง Plot แผนภูมิ (หรือกราฟนั่นเอง) แต่ว่าพูดถึง Pandas อย่างเดียวคงไม่ได้ เพราะการแสดงผลที่งดงามนั้นเราจะแสดงผลกันใน Jupyter Lab (มันมี Jupyter Notebook ด้วยนะ) แต่ผู้เขียนถูกจริตกับ Jupyter Lab มากกว่าครับ

วันนี้เราคงไม่ได้พูดถึงเบื้องลึกอะไรกันมากนะครับ เรามาลองเล่น Pandas และลอง Plot กราฟไปด้วยกันนะครับ

สร้าง Environment และเรียกใช้ Jupyter Lab

mkvirtualenv pandas-test
ls
workon pandas
pip install pandas jupyterlab
jupyter-lab

เริ่มใช้งาน Jupyter

การใช้งาน Jupyter ให้แปะโค๊ดลงไปใน Cell ได้เลย แล้วกดรันโดยการกด Shift + Enter ครับ ถ้ารันสำเร็จแล้วจะมี ตัวเลขลำดับของการรันขึ้นข้างหน้า Cell จกภาพตัวอย่างจะเป็นการติดตั้ง pandas และ matplotlib ทั้งหมดนี้จะติดตั้งเข้าไปอยู่ใน Environment pandas-test ที่สร้างไปข้างบนนั่นเองครับ

หลังจากนั้นเราเริ่มโหลดข้อมูลจาก CSV ขึ้นมาโดยใช้ Pandas โดยให้กำหนด header ให้มีชื่อตามลำดับดังนี้ ['time', 'date', 'temp']

df = pd.read_csv('20200401.CSV', names=['time','date','temp'])
df.set_index("time")

หลังจากนั้นเราจะแปลงข้อมูลให้เป็น datetime แบบ manual โดยการใช้คำสั่งของ pandas นั่นก็คือ pd.to_dataframe นั่นเอง

df ['time'] = pd.to_datetime(df['time'])
df ['date'] = pd.to_datetime(df['date'])

เมื่อเรียบร้อยหมดแล้ว เราสามารถตรวจสอบข้อมูลต่างๆ ใน DataFrame ของเราโดยการเรียกคำสั่ง df.dtypes

Plot กราฟ

เราสามารถใช้ matplotlib ใน Jupyter ได้ครับ แต่ว่าเราต้อง Config มันก่อนด้วย ไม่งั้นมันจะออกมาเป็นขนาดเล็ก ไม่สวยเท่าไหร่

%matplotlib inline
 import matplotlib.pyplot as plt
 plt.rcParams['figure.dpi'] = 100
 plt.rcParams["figure.figsize"] = (30, 5) # (w, h)

เตรียมข้อมูล

ผมตั้งโจทย์ไว้ 2 โจทย์ครับ คือนับข้อมูลว่าใน 1 ชั่วโมง เราเก็บค่าได้กี่ค่า และ มีการ Resampling โดยให้ Aggregrate ข้อมูลราย 5 นาที และใช้ median เข้ามา Aggregrate ข้อมูลครับ เนื่องจากข้อมูลมีจำนวนเยอะ (1672 Rows) เราพล๊อตกราฟไม่ไหว ซึ่งข้อมูลเรามีหน้าตาแบบนี้ครับ

เขียนโค๊ดได้แบบนี้

groupBy

ใช้ df.groupby เพื่อให้รวบรวมข้อมูลให้เราเป็นราย 1 ชั่วโมง และใส่ Field count เพิ่มเข้าไปให้เราด้วย อาจจะมีวิธีที่ดีกว่านี้ ไว้เราค่อยมาว่ากันใหม่นะครับ

resample

ก่อนที่เราจะ Resample เพื่อสร้างข้อมูลใน เรท 5Minute เราต้อง Set index ให้เป็นฟิลด์ประเภท datetime ซะก่อน หลังจากนั้นเราจะเรียก df.dropna เพื่อลบข้อมูลที่ไม่มีออกไป สะดวกเนอะ!

df = df.set_index('time')
df2 = df.resample('5Min').median().reset_index()
df2.dropna(inplace=True)

พล๊อตกราฟ!

ผมใช้ matplotlib เพื่อสั่ง plot โดยกำหนด format ของ time โดยการใช้คำสั่ง strftime เข้ามาช่วย และพล๊อตเข้ากับข้อมูล df2.temp

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')

plt.title("Temperature (DS3231)")
plt.xticks(rotation=90)
plt.plot(df2.time.dt.strftime('%H:%M'), df2.temp)

ผลลัพธ์

ลุยกันมาถึงตอนนี้แล้ว ถือว่าทำได้ดีเลยครับวันนี้ ใครสนใจข้อมูล และ Source Code สามารถกดไปดู Notebook ได้ที่นี่เลยครับ >> https://github.com/cmmakerclub/pandas-sensor/blob/master/csv.ipynb

Leave a Comment