Data Acquisition (Pandas)
Table of Contents
- 1) การนำเข้าข้อมูล
- 1.1) ตัวอย่างข้อมูลโควิด (csv)
- 1.2) ตัวอย่างข้อมูลปริมาณน้ำมัน (csv)
- 1.3) ตัวอย่างข้อมูลหน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมท้องถิ่น (xlsx)
- 1.4) ตัวอย่างข้อมูล gapminder (json)
- 2) ประโยชน์ของ class dataframe
- ในการทำงาน Data Science จะต้องทำงานกับข้อมูล
- ก่อนที่จะทำงานกับข้อมูลได้ เราต้องสามารถนำข้อมูลเข้ามาในโปรแกรมเราให้ได้ก่อน
- เรารู้จักกับการนำเข้าข้อมูลสองแบบแล้ว คือ
- คำสั่ง
input()
ซึ่งนำเข้าข้อมูลทีละบรรทัด - อ่านไฟล์เข้า เช่น
open("filename.csv", "r")
ซึ่งอ่านไฟล์ข้อมูลเข้ามาเป็น text
- คำสั่ง
- Lab นี้จะแนะนำ extension library ชื่อ
pandas
ที่จะอำนวยความสะดวกในการอ่านข้อมูลเป็นโครงสร้างแบบตาราง (class ประเภท dataframe ใน pandas) - library documentation: https://pandas.pydata.org/docs/
1) การนำเข้าข้อมูล
1.1) ตัวอย่างข้อมูลโควิด (csv)
ต่อไปนี้จะเป็นการนำเข้าข้อมูลประเภท csv
(comma-separated values) จาก https://data.go.th/dataset/labscovid19
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/tj-14/mirror.data.go.th/main/data/labscovid19_update080365.csv", encoding="ISO-8859-11")
encoding="ISO-8859-11"
ในการอ่านภาษาไทย ขึ้นอยู่กับประเภทของไฟล์คำสั่งของ pandas
มีการทำงานดังนี้
pd
เป็นการเรียก library pandas (จากที่เราimport pandas as pd
).read_csv(url)
เป็นการเรียก methodread_csv
และระบุที่อยู่ (url
) ของไฟล์ข้อมูลที่เราต้องการอ่าน
ในกรณีที่มีไฟล์อยู่ในเครื่องตัวเองสามารถใช้ path
แทน url
ได้เหมือน ฟังก์ชัน open
ของ Python
โดยการเรียก df ธรรมดาจะแสดงผลทั้งตาราง ส่วน
df.head()
จะแสดง 5 แถวแรกdf.tail()
จะแสดง 5 แถวสุดท้าย
df.head()
orgth | orgen | telephone | address | website | healtharea | agency | province | district | area | npsts | pooledsaliva | pooledswab | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | ศูนย์วิทยาศาสตร์การแพทย์ที่ 1 เชียงใหม่ | Regional Medical Sciences Center 1 Chiang Mai | 0-5311-2188-90 | 191 หมู่ 8 ต.ดอนแก้ว อ.แม่ริม จ.เชียงใหม่ 50180 | http://webapp1.dmsc.moph.go.th/cm1/web/post-group/25/2 | เขต 1 | ภาครัฐ | เชียงใหม่ | แม่ริม | ต่างจังหวัด | เปิดตรวจแล้ว | เปิดตรวจแล้ว | เปิดตรวจแล้ว |
1 | ศูนย์วิทยาศาสตร์การแพทย์ที่ 1/1 เชียงราย | Regional Medical Sciences Center 1/1 Chiang Rai | 0-5317-6224-6 | 148 หมู่ 3 ตำบลนางแล อำเภอเมือง จังหวัดเชียงราย 57100 | http://cri.dmsc.moph.go.th/ | เขต 1 | ภาครัฐ | เชียงราย | เมืองเชียงราย | ต่างจังหวัด | เปิดตรวจแล้ว | เปิดตรวจแล้ว | เปิดตรวจแล้ว |
2 | สำนักงานป้องกันควบคุมโรคที่ 1 เชียงใหม่ | The Office of Disease Prevention and Control 1 Chiang Mai | 0-5314-0774 | 447 ถนนเชียงใหม่-ลำพูน ตำบลวัดเกต อำเภอเมือง จังหวัดเชียงใหม่ 50000 | https://ddc.moph.go.th/odpc1/ | เขต 1 | ภาครัฐ | เชียงใหม่ | เมืองเชียงใหม่ | ต่างจังหวัด | เปิดตรวจแล้ว | NaN | เปิดตรวจแล้ว |
3 | โรงพยาบาลนครพิงค์ | Nakornping Hospital | 0-5399-9200 | 159 ม.10 ถ.โชตนา ต.ดอนแก้ว อ.แม่ริม จ.เชียงใหม่ 50180 | http://www.nkp-hospital.go.th/th/ | เขต 1 | ภาครัฐ | เชียงใหม่ | แม่ริม | ต่างจังหวัด | เปิดตรวจแล้ว | เปิดตรวจแล้ว | เปิดตรวจแล้ว |
4 | โรงพยาบาลลำปาง | Lampang Hospital | 0-5423-7400 | 28/3 ห้องอณูชีวโมเลกุล กลุ่มงานเทคนิคการแพทย์ โรงพยาบาลลำปาง 52000 | http://www.lph.go.th/lpweb/ | เขต 1 | ภาครัฐ | ลำปาง | เมืองลำปาง | ต่างจังหวัด | เปิดตรวจแล้ว | เปิดตรวจแล้ว | เปิดตรวจแล้ว |
df.tail()
orgth | orgen | telephone | address | website | healtharea | agency | province | district | area | npsts | pooledsaliva | pooledswab | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
508 | งานอณูชีววิทยา โรงพยาบาลราชวิถี | NaN | 0-2206-2900 ต่อ 40610-2 | NaN | http://www.rajavithi.go.th/rj/medtech/biomolecular-laboratory%E0%B8%AB%E0%B9%89%E0%B8%AD%E0%B8%87%E0%B8%9B%E0%B8%8F%E0%B8%B4%E0%B8%9A%E0%B8%B1%E0%B8%95%E0%B8%B4%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%AD%E0%B8%93%E0%B8%B9%E0%B8%8A%E0%B8%B5/ | เขต 13 | ภาครัฐ | กรุงเทพมหานคร | ราชเทวี | กรุงเทพและปริมณฑล | เปิดตรวจแล้ว | NaN | NaN |
509 | งานจุลชีววิทยา โรงพยาบาลราชวิถี | NaN | 0-2206-2900 ต่อ 3142, 3143 | NaN | http://www.rajavithi.go.th/rj/medtech/microbiology%E0%B8%87%E0%B8%B2%E0%B8%99%E0%B8%88%E0%B8%B8%E0%B8%A5%E0%B8%8A%E0%B8%B5%E0%B8%A7%E0%B8%A7%E0%B8%B4%E0%B8%97%E0%B8%A2%E0%B8%B2/ | เขต 13 | ภาครัฐ | กรุงเทพมหานคร | ราชเทวี | กรุงเทพและปริมณฑล | เปิดตรวจแล้ว | NaN | NaN |
510 | โรงพยาบาลประโคนชัย | NaN | 0-4467-0103 | NaN | https://www.facebook.com/pkchospital | เขต 9 | ภาครัฐ | บุรีรัมย์ | ประโคนชัย | ต่างจังหวัด | เปิดตรวจแล้ว | NaN | NaN |
511 | กรุงเทพพยาธิ-แลป คลินิกเทคนิคการแพทย์ | NaN | 0-2619-2909 | NaN | https://www.bpl.co.th/pweb/ | เขต 13 | เอกชน | กรุงเทพมหานคร | พญาไท | กรุงเทพและปริมณฑล | เปิดตรวจแล้ว | NaN | NaN |
512 | เอ็นเฮลท์ คลินิกเทคนิคการแพทย์ | NaN | 0-2019-9921, 09-8650-6735 | NaN | https://www.nhealth-asia.com/th/product/14 | เขต 13 | เอกชน | กรุงเทพมหานคร | บางแค | กรุงเทพและปริมณฑล | เปิดตรวจแล้ว | NaN | NaN |
1.2) ตัวอย่างข้อมูลปริมาณน้ำมัน (csv)
ข้อมูลจาก https://data.go.th/dataset/e20-station
df = pd.read_csv(
"https://raw.githubusercontent.com/tj-14/mirror.data.go.th/main/data/05_e20_19_11nov_sta.csv",
encoding="ISO-8859-11"
)
df.head()
ตารางแสดงปริมาณ น้ำมันแก๊สโซฮอล์อี 20 ที่ผู้ค้าน้ำมันจำหน่ายให้ลูกค้าและผู้ใช้ในจังหวัดต่าง ๆ | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | Unnamed: 6 | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | Unnamed: 10 | Unnamed: 11 | Unnamed: 12 | Unnamed: 13 | Unnamed: 14 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | สาขา สถานีบริการ | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1 | ตั้งแต่เดือน พฤศจิกายน ถึง เดือน พฤศจิกายน 2562 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ปริมาณ /พันลิตร |
3 | ลำดับที่ | จังหวัด | ปตท. | เชลล์ | เอสโซ่ | เชฟรอน(ไทย) | บางจาก | ซัสโก้ | พีทีจี | ไทยออยล์ | ซัสโก้ ดีลเลอร์ส | สยามเฆมี | ปตท. ค้าปลีก | ปตท. น้ำมันและการค้าปลีก | รวมทั้งสิ้น |
4 | NaN | กรุงเทพฯ และปริมณฑล | 2,033 | 12,012 | 11,788 | 1,513 | 17,163 | 553 | 107 | NaN | 352 | 4 | 5,546 | 15,499 | 66,571 |
1.3) ตัวอย่างข้อมูลหน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมท้องถิ่น (xlsx)
ใช้ read_excel
นำเข้าข้อมูลประเภท excel จาก https://data.go.th/dataset/conservation-unit
จำเป็นต้องระบุ engine='openpyxl'
ในการอ่านไฟล์ .xlsx
หาก labpy ขึ้น error ว่าไม่เจอ openpyxl ให้รันคำสั่ง !pip install openpyxl
df = pd.read_excel(
"https://github.com/tj-14/mirror.data.go.th/blob/main/data/conservation_unit-march-2021.xlsx?raw=true",
engine='openpyxl'
)
df.head()
ลำดับที่ | ชื่อหน่วย | หน่วยงานรับผิดชอบ | เลขที่ | ถนน | ตำบล | อำเภอ | จังหวัด | รหัสไปรษณีย์ | ภาค | ละติจูด | ลองติจูด | โทรศัพท์ | โทรสาร | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | หน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมท้องถิ่นจังหวัดลำปาง | สำนักศิลปะและวัฒนธรรมมหาวิทยาลัยราชภัฏลำปาง | 119 | ลำปาง-แม่ทะ | ชมพู | เมืองลำปาง | ลำปาง | 52100 | เหนือ | 18.233935 | 99.487555 | 0 5423 7399 ต่อ 6701-2 | 0 5423 7388-9 |
1 | 2 | หน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมท้องถิ่นจังหวัดลำพูน | โรงเรียนส่วนบุญโญปถัมภ์ | 12 | ลำพูน-ป่าซาง | ในเมือง | เมืองลำพูน | ลำพูน | 51000 | เหนือ | 18.573028 | 99.000938 | 0 5353 5304 | 0 5351 1060 |
2 | 3 | หน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมท้องถิ่นจังหวัดเชียงใหม่ | มหาวิทยาลัยราชภัฏเชียงใหม่ | 202 | ช้างเผือก | ช้างเผือก | เมืองเชียงใหม่ | เชียงใหม่ | 50300 | เหนือ | 18.806228 | 98.986050 | 0 5388 5861 | 0 5388 5880 |
3 | 4 | หน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมจังหวัดแม่ฮ่องสอน | โรงเรียนห้องสอนศึกษา | 1/17 | ขุนลุมประพาส | จองคำ | เมืองแม่ฮ่องสอน | แม่ฮ่องสอน | 58000 | เหนือ | 19.311304 | 97.963881 | 0 5361 1349 | 0 5361 2079 |
4 | 5 | หน่วยอนุรักษ์สิ่งแวดล้อมธรรมชาติและศิลปกรรมท้องถิ่นจังหวัดน่าน | โรงเรียนสตรีศรีน่าน | 226/24 | มะโน | ในเวียง | เมืองน่าน | น่าน | 55000 | เหนือ | 18.777116 | 100.780411 | 0 5471 0373 | 0 5477 3079 |
1.4) ตัวอย่างข้อมูล gapminder (json)
df = pd.read_json("https://raw.githubusercontent.com/vega/vega-datasets/master/data/gapminder.json")
df.head()
year | country | cluster | pop | life_expect | fertility | |
---|---|---|---|---|---|---|
0 | 1955 | Afghanistan | 0 | 8891209 | 30.332 | 7.7 |
1 | 1960 | Afghanistan | 0 | 9829450 | 31.997 | 7.7 |
2 | 1965 | Afghanistan | 0 | 10997885 | 34.020 | 7.7 |
3 | 1970 | Afghanistan | 0 | 12430623 | 36.088 | 7.7 |
4 | 1975 | Afghanistan | 0 | 14132019 | 38.438 | 7.7 |
read_csv() | |
read_excel() | |
read_json() |
read_csv() | |
read_excel() | |
read_json() |
ให้นักเรียนนำเข้าข้อมูลที่เลือกเองจาก แหล่งข้อมูล ด้วย Pandas ให้อ.ดูใน labpy หรือ DataSpell
2) ประโยชน์ของ class dataframe
- การอ่านข้อมูลเข้ามาด้วย
pd.read_csv
หรือpd.read_excel
จะเก็บข้อมูลอยู่ใน classDataFrame
- class
DataFrame
มี method ให้เราเรียกใช้ได้หลากหลายซึ่งจะอำนวยความสะดวก
2.1) General
เราจะเริ่มด้วยการสร้าง DataFrame จากการสุ่มค่าด้วย np.random.rand
ก่อน
import numpy as np
df = pd.DataFrame(np.random.rand(10, 4), columns=['A', 'B', 'C', 'D'])
df
A | B | C | D | |
---|---|---|---|---|
0 | 0.782912 | 0.603829 | 0.500766 | 0.424004 |
1 | 0.680229 | 0.372327 | 0.375480 | 0.278074 |
2 | 0.433922 | 0.579086 | 0.936927 | 0.309911 |
3 | 0.034151 | 0.654472 | 0.311490 | 0.322064 |
4 | 0.202609 | 0.465183 | 0.165454 | 0.768956 |
5 | 0.400387 | 0.342838 | 0.409134 | 0.726753 |
6 | 0.995054 | 0.378604 | 0.153604 | 0.997026 |
7 | 0.871528 | 0.121654 | 0.569885 | 0.809992 |
8 | 0.703073 | 0.225356 | 0.895510 | 0.069899 |
9 | 0.199475 | 0.027062 | 0.236958 | 0.947021 |
ข้อมูลประเภท DataFrame มีส่วนสำคัญหลักคือ
- index: ค่ากำกับแต่ละแถว
- column: ค่ากำกับแต่ละคอลัมภ์
- value: ค่าภายในตาราง
ซึ่งเราสามารถเรียกดูค่าได้ดังนี้
print(df.index)
print(df.columns)
print(df.values)
RangeIndex(start=0, stop=10, step=1)
Index(['A', 'B', 'C', 'D'], dtype='object')
[[0.7829119 0.60382855 0.50076637 0.42400391]
[0.68022882 0.37232697 0.37547956 0.27807436]
[0.43392244 0.57908639 0.93692711 0.30991087]
[0.03415112 0.65447155 0.3114905 0.32206372]
[0.20260941 0.46518289 0.16545388 0.76895575]
[0.40038741 0.34283772 0.40913372 0.72675322]
[0.9950541 0.37860425 0.15360411 0.99702591]
[0.87152813 0.12165434 0.56988496 0.80999185]
[0.70307289 0.22535636 0.89550976 0.06989925]
[0.19947545 0.02706189 0.23695781 0.94702101]]
2.2) Quick Data Summary
ตัวอย่างฟังก์ชันที่มีประโยชน์ของ DataFrame คือ .describe()
ที่สามารถบอกค่าสถิติเบื้องต้นของแต่ละคอลัมพ์ได้ทันที
df.describe()
A | B | C | D | |
---|---|---|---|---|
count | 10.000000 | 10.000000 | 10.000000 | 10.000000 |
mean | 0.530334 | 0.377041 | 0.455521 | 0.565370 |
std | 0.322788 | 0.207873 | 0.277456 | 0.321764 |
min | 0.034151 | 0.027062 | 0.153604 | 0.069899 |
25% | 0.252054 | 0.254727 | 0.255591 | 0.312949 |
50% | 0.557076 | 0.375466 | 0.392307 | 0.575379 |
75% | 0.762952 | 0.550611 | 0.552605 | 0.799733 |
max | 0.995054 | 0.654472 | 0.936927 | 0.997026 |
2.3) Selection
การเลือกคอลัมภ์ (จะได้ออกมาเป็น class pd.Series
) สามารถใช้ df['A']
หรือ df.A
ซึ่งจะได้
0 0.782912
1 0.680229
2 0.433922
3 0.034151
4 0.202609
5 0.400387
6 0.995054
7 0.871528
8 0.703073
9 0.199475
Name: A, dtype: float64
สามารถทำ slicing ได้ เช่น
df[0:3]
A | B | C | D | |
---|---|---|---|---|
0 | 0.782912 | 0.603829 | 0.500766 | 0.424004 |
1 | 0.680229 | 0.372327 | 0.375480 | 0.278074 |
2 | 0.433922 | 0.579086 | 0.936927 | 0.309911 |
เราสามารถเลือกแต่ละแถวได้ด้วย
df.loc[7]
จะได้
A 0.871528
B 0.121654
C 0.569885
D 0.809992
Name: 7, dtype: float64
สามารถระบุทั้ง row และ column ได้เช่นกัน
df.loc[7, 'A']
จะได้
0.8715281334680098
เลือกด้วยตำแหน่ง (ในกรณีที่ index ไม่ใช่ตัวเลขเริ่มจาก 0)
df.iloc[3]
จะได้
A 0.034151
B 0.654472
C 0.311490
D 0.322064
Name: 3, dtype: float64
ซึ่งทำ slicing ด้วยตำแหน่งได้เช่นกัน
df.iloc[3:5, 0:2]
ได้
A B
3 0.034151 0.654472
4 0.202609 0.465183
df.iloc[:, 1:3]
ได้
B C
0 0.603829 0.500766
1 0.372327 0.375480
2 0.579086 0.936927
3 0.654472 0.311490
4 0.465183 0.165454
5 0.342838 0.409134
6 0.378604 0.153604
7 0.121654 0.569885
8 0.225356 0.895510
9 0.027062 0.236958
iloc
เลือกตำแหน่ง row และ column จะไม่ได้ใช้ 'A', 'B', 'C', 'D'
เจาะจงตำแหน่งที่ 1, 1 เช่น
df.iloc[1, 1]
จะได้
0.37232696730152004
จาก df ที่มีค่าดังนี้
A | B | C | D | |
---|---|---|---|---|
0 | 0.782912 | 0.603829 | 0.500766 | 0.424004 |
1 | 0.680229 | 0.372327 | 0.375480 | 0.278074 |
2 | 0.433922 | 0.579086 | 0.936927 | 0.309911 |
3 | 0.034151 | 0.654472 | 0.311490 | 0.322064 |
4 | 0.202609 | 0.465183 | 0.165454 | 0.768956 |
5 | 0.400387 | 0.342838 | 0.409134 | 0.726753 |
6 | 0.995054 | 0.378604 | 0.153604 | 0.997026 |
7 | 0.871528 | 0.121654 | 0.569885 | 0.809992 |
8 | 0.703073 | 0.225356 | 0.895510 | 0.069899 |
9 | 0.199475 | 0.027062 | 0.236958 | 0.947021 |
print(df.iloc[1, 3])
จาก df เดิม ผลลัพธ์จากคำสั่งต่อไปนี้คืออะไร (ตอบเป็นทศนิยม 3 ตำแหน่ง)
print(df.loc[3, 'B'])
2.4) Operations
DataFrame มี method หาค่าพื้นฐานทางคณิตศาสตร์ให้ใช้เช่นกัน
จาก DataFrame df
ที่มีค่า
A | B | C | D | |
---|---|---|---|---|
0 | 0.782912 | 0.603829 | 0.500766 | 0.424004 |
1 | 0.680229 | 0.372327 | 0.375480 | 0.278074 |
2 | 0.433922 | 0.579086 | 0.936927 | 0.309911 |
3 | 0.034151 | 0.654472 | 0.311490 | 0.322064 |
4 | 0.202609 | 0.465183 | 0.165454 | 0.768956 |
5 | 0.400387 | 0.342838 | 0.409134 | 0.726753 |
6 | 0.995054 | 0.378604 | 0.153604 | 0.997026 |
7 | 0.871528 | 0.121654 | 0.569885 | 0.809992 |
8 | 0.703073 | 0.225356 | 0.895510 | 0.069899 |
9 | 0.199475 | 0.027062 | 0.236958 | 0.947021 |
หากหาค่าต่าง ๆ จะได้
df.mean()
A 0.530334
B 0.377041
C 0.455521
D 0.565370
dtype: float64
df.sum()
A 5.303342
B 3.770411
C 4.555208
D 5.653700
dtype: float64
df.std()
A 0.322788
B 0.207873
C 0.277456
D 0.321764
dtype: float64
ซึ่ง DataFrame จะหาค่าต่าง ๆ แยกให้ตามแต่ละคอลัมภ์
จาก df เดิม ผลลัพธ์จากคำสั่งต่อไปนี้คืออะไร (ตอบเป็นทศนิยม 3 ตำแหน่ง)
df.max()['A']
จาก df เดิม ผลลัพธ์จากคำสั่งต่อไปนี้คืออะไร (ตอบเป็นทศนิยม 3 ตำแหน่ง)
df.min()['B']
ให้นักเรียนหาค่าพื้นฐานทางสถิติดังต่อไปนี้จากคอลัมน์ที่เป็นไปได้ (คอลัมน์ที่เป็นตัวเลข) ในข้อมูลที่นักเรียนนำเข้ามาจาก Checkoff ที่แล้วใน labpy หรือ DataSpell
- ค่าเฉลี่ย
- ค่ามัธยฐาน