หลังจากที่เรา การติดตั้ง 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