Data Cleansing (NumPy & Pandas)
Table of Contents
- 1) การจัดการรูปแบบ
- 1.1) ตัวอย่างปัญหา data types และวิธีการระบุ thousands
- 1.2) ตัวอย่างปัญหาชื่อ columns และวิธีการ set columns, slicing, reset_index
- 2) การจัดการค่า
- ในการทำงานจริง ข้อมูลส่วนใหญ่จะมาในสภาพที่ไม่พร้อมใช้งานได้ทันที
- จะมีกระบวนการเตรียมความพร้อมข้อมูลก่อนนำไปประมวลผล
- เรียกว่า data cleansing หรือ data preprocessing
- ทั้งนี้ สภาพของข้อมูลจะมีหลากหลายมาก lab นี้จึงอาจจะยกตัวอย่างมาได้ไม่ครบถ้วน
1) การจัดการรูปแบบ
1.1) ตัวอย่างปัญหา data types และวิธีการระบุ thousands
เริ่มด้วยการอ่านข้อมูลปริมาณจราจรบนทางหลวง ปี 2563 https://data.go.th/dataset/highwaystraffic2563
encoding="ISO-8859-11"
ในการอ่านภาษาไทย ขึ้นอยู่กับประเภทของไฟล์import pandas as pd
df = pd.read_csv(
"https://github.com/tj-14/mirror.data.go.th/raw/main/data/63.csv",
encoding="ISO-8859-11",
)
df.head()
ทางหลวงสาย | ตอนควบคุม | ชื่อสายทาง | จุดสำรวจ | รถยนต์นั่ง (ไม่เกิน 7 คน) | รถยนต์นั่ง (เกิน 7 คน) | รถโดยสารขนาดเล็ก | รถโดยสารขนาดกลาง | รถโดยสารขนาดใหญ่ | รถบรรทุกขนาดเล็ก ( 4 ล้อ) | รถบรรทุกขนาด 2 เพลา (6 ล้อ) | รถบรรทุกขนาด 3 เพลา (10 ล้อ) | รถบรรทุกพ่วง (มากกว่า 3 เพลา) | รถบรรทุกกึ่งพ่วง (มากกว่า 3 เพลา) | รวม | % ของยานยนต์หนัก | จักรยาน 2 ล้อ และ จักรยาน 3 ล้อ | สามล้อเครื่องและจักรยานยนต์ | แขวงทางหลวง | จังหวัด | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 102 | แยก คปอ. - สนามกีฬาธูปะเตมีย์ | 25+556 | 19,024 | 7,459 | 15 | 695 | 1,266 | 6,731 | 522 | 177 | 58 | 65 | 36,012 | 7.73 | 40 | 9,437 | ขท.กรุงเทพ | กรุงเทพมหานคร |
1 | 1 | 201 | สนามกีฬาธูปะเตมีย์ - ต่างระดับคลองหลวง | 35+550 | 179,799 | 41,887 | 2,317 | 4,873 | 13,781 | 69,678 | 10,445 | 4,613 | 1,350 | 1,003 | 329,746 | 10.94 | 281 | 18,953 | ขท.ปทุมธานี | ปทุมธานี |
2 | 1 | 202 | ต่างระดับคลองหลวง - ประตูน้ำพระอินทร์ | 48+100 | 88,775 | 38,115 | 3,710 | 6,284 | 10,501 | 54,244 | 18,089 | 3,433 | 2,471 | 1,586 | 227,208 | 18.65 | 64 | 13,728 | ขท.ปทุมธานี | พระนครศรีอยุธยา |
3 | 1 | 300 | ประตูน้ำพระอินทร์ - หนองแค | 60+800 | 32,416 | 26,851 | 7,781 | 2,670 | 3,454 | 8,219 | 7,342 | 8,422 | 7,236 | 7,333 | 111,724 | 32.63 | 0 | 1,540 | ขท.อยุธยา | พระนครศรีอยุธยา |
4 | 1 | 300 | ประตูน้ำพระอินทร์ - หนองแค | 67+300 | 35,326 | 20,998 | 8,300 | 2,123 | 3,339 | 17,087 | 16,201 | 10,811 | 10,718 | 9,635 | 134,538 | 39.27 | 0 | 1,544 | ขท.อยุธยา | พระนครศรีอยุธยา |
เราสามารถใช้คำสั่ง df.info()
สำหรับการดูประเภทข้อมูลแต่ละคอลัมน์เบื้องต้นได้
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2701 entries, 0 to 2700
Data columns (total 20 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ทางหลวงสาย 2701 non-null int64
1 ตอนควบคุม 2701 non-null int64
2 ชื่อสายทาง 2701 non-null object
3 จุดสำรวจ 2701 non-null object
4 รถยนต์นั่ง (ไม่เกิน 7 คน) 2701 non-null object
5 รถยนต์นั่ง (เกิน 7 คน) 2701 non-null object
6 รถโดยสารขนาดเล็ก 2701 non-null object
7 รถโดยสารขนาดกลาง 2701 non-null object
8 รถโดยสารขนาดใหญ่ 2701 non-null object
9 รถบรรทุกขนาดเล็ก ( 4 ล้อ) 2701 non-null object
10 รถบรรทุกขนาด 2 เพลา (6 ล้อ) 2701 non-null object
11 รถบรรทุกขนาด 3 เพลา (10 ล้อ) 2701 non-null object
12 รถบรรทุกพ่วง (มากกว่า 3 เพลา) 2701 non-null object
13 รถบรรทุกกึ่งพ่วง (มากกว่า 3 เพลา) 2701 non-null object
14 รวม 2701 non-null object
15 % ของยานยนต์หนัก 2701 non-null float64
16 จักรยาน 2 ล้อ และ จักรยาน 3 ล้อ 2701 non-null object
17 สามล้อเครื่องและจักรยานยนต์ 2701 non-null object
18 แขวงทางหลวง 2701 non-null object
19 จังหวัด 2701 non-null object
dtypes: float64(1), int64(2), object(17)
memory usage: 422.2+ KB
ทางหลวงสาย
มี Dtype เป็นอะไรnull | |
object | |
int64 | |
float64 |
รถโดยสารขนาดเล็ก
มี Dtype เป็นอะไรnull | |
object | |
int64 | |
float64 |
จะเห็นว่าคอลัมน์ที่ควรเป็นตัวเลข เช่น รถโดยสารขนาดเล็ก
นั้นมี Dtype
เป็น object
ซึ่งไม่ใช่ int64
(จำนวนเต็ม) หรือ float64
(จำนวนจริง)
เพราะว่าตัวเลข 2,317
นั้นมี ,
(comma) อยู่ pandas
จึงคิดว่าเป็นข้อความแทนที่จะเป็นตัวเลข
เราสามารถระบุ parameter thousands=','
ใน pd.read_csv
เพิ่มเติมได้เพื่อบอก pandas
ว่า ,
นั้นเป็นสัญลักษณ์คั่นหลักพันของตัวเลข
thousands=','
เป็นการระบุว่าเราใช้ลูกน้ำ ,
เป็นตัวระบุเลข ณ ตำแหน่งหลักพัน
หากไม่ระบุแล้ว pandas จะอ่าน 1,000
เป็น string แทนที่ควรจะเป็นตัวเลข
df = pd.read_csv(
"https://github.com/tj-14/mirror.data.go.th/raw/main/data/63.csv",
encoding="ISO-8859-11",
thousands=','
)
df.head()
ทางหลวงสาย | ตอนควบคุม | ชื่อสายทาง | จุดสำรวจ | รถยนต์นั่ง (ไม่เกิน 7 คน) | รถยนต์นั่ง (เกิน 7 คน) | รถโดยสารขนาดเล็ก | รถโดยสารขนาดกลาง | รถโดยสารขนาดใหญ่ | รถบรรทุกขนาดเล็ก ( 4 ล้อ) | รถบรรทุกขนาด 2 เพลา (6 ล้อ) | รถบรรทุกขนาด 3 เพลา (10 ล้อ) | รถบรรทุกพ่วง (มากกว่า 3 เพลา) | รถบรรทุกกึ่งพ่วง (มากกว่า 3 เพลา) | รวม | % ของยานยนต์หนัก | จักรยาน 2 ล้อ และ จักรยาน 3 ล้อ | สามล้อเครื่องและจักรยานยนต์ | แขวงทางหลวง | จังหวัด | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 102 | แยก คปอ. - สนามกีฬาธูปะเตมีย์ | 25+556 | 19024 | 7459 | 15 | 695 | 1266 | 6731 | 522 | 177 | 58 | 65 | 36012 | 7.73 | 40 | 9437 | ขท.กรุงเทพ | กรุงเทพมหานคร |
1 | 1 | 201 | สนามกีฬาธูปะเตมีย์ - ต่างระดับคลองหลวง | 35+550 | 179799 | 41887 | 2317 | 4873 | 13781 | 69678 | 10445 | 4613 | 1350 | 1003 | 329746 | 10.94 | 281 | 18953 | ขท.ปทุมธานี | ปทุมธานี |
2 | 1 | 202 | ต่างระดับคลองหลวง - ประตูน้ำพระอินทร์ | 48+100 | 88775 | 38115 | 3710 | 6284 | 10501 | 54244 | 18089 | 3433 | 2471 | 1586 | 227208 | 18.65 | 64 | 13728 | ขท.ปทุมธานี | พระนครศรีอยุธยา |
3 | 1 | 300 | ประตูน้ำพระอินทร์ - หนองแค | 60+800 | 32416 | 26851 | 7781 | 2670 | 3454 | 8219 | 7342 | 8422 | 7236 | 7333 | 111724 | 32.63 | 0 | 1540 | ขท.อยุธยา | พระนครศรีอยุธยา |
4 | 1 | 300 | ประตูน้ำพระอินทร์ - หนองแค | 67+300 | 35326 | 20998 | 8300 | 2123 | 3339 | 17087 | 16201 | 10811 | 10718 | 9635 | 134538 | 39.27 | 0 | 1544 | ขท.อยุธยา | พระนครศรีอยุธยา |
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2701 entries, 0 to 2700
Data columns (total 20 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ทางหลวงสาย 2701 non-null int64
1 ตอนควบคุม 2701 non-null int64
2 ชื่อสายทาง 2701 non-null object
3 จุดสำรวจ 2701 non-null object
4 รถยนต์นั่ง (ไม่เกิน 7 คน) 2701 non-null int64
5 รถยนต์นั่ง (เกิน 7 คน) 2701 non-null int64
6 รถโดยสารขนาดเล็ก 2701 non-null int64
7 รถโดยสารขนาดกลาง 2701 non-null int64
8 รถโดยสารขนาดใหญ่ 2701 non-null int64
9 รถบรรทุกขนาดเล็ก ( 4 ล้อ) 2701 non-null int64
10 รถบรรทุกขนาด 2 เพลา (6 ล้อ) 2701 non-null int64
11 รถบรรทุกขนาด 3 เพลา (10 ล้อ) 2701 non-null int64
12 รถบรรทุกพ่วง (มากกว่า 3 เพลา) 2701 non-null int64
13 รถบรรทุกกึ่งพ่วง (มากกว่า 3 เพลา) 2701 non-null int64
14 รวม 2701 non-null int64
15 % ของยานยนต์หนัก 2701 non-null float64
16 จักรยาน 2 ล้อ และ จักรยาน 3 ล้อ 2701 non-null int64
17 สามล้อเครื่องและจักรยานยนต์ 2701 non-null int64
18 แขวงทางหลวง 2701 non-null object
19 จังหวัด 2701 non-null object
dtypes: float64(1), int64(15), object(4)
memory usage: 422.2+ KB
ทางหลวงสาย
มี Dtype เป็นอะไรnull | |
object | |
int64 | |
float64 |
รถโดยสารขนาดเล็ก
มี Dtype เป็นอะไรnull | |
object | |
int64 | |
float64 |
จะเห็นว่าคอลัมน์ที่เป็นตัวเลข เช่น รถโดยสารขนาดเล็ก
นั้นมี Dtype
เป็น int64
(จำนวนเต็ม) แล้ว
1.2) ตัวอย่างปัญหาชื่อ columns และวิธีการ set columns, slicing, reset_index
ในหัวข้อนี้จะมีเนื้อหาเหมือนกับในวิดีโอ demo การจัดการข้อมูลใน pandas (youtube)
เริ่มด้วยการอ่านข้อมูลผลผลิตทุเรียนแยกตามจังหวัด ปี 2562 https://data.go.th/dataset/39e51846-3314-4f88-8fbc-0ca070084141
df = pd.read_excel("https://data.go.th/dataset/39e51846-3314-4f88-8fbc-0ca070084141/resource/756ca215-5cd3-454f-be5a-04264c31101e/download/untitled.xlsx")
df.head()
สำนักงานเศรษฐกิจการเกษตร | สินค้าเกษตรทุเรียน | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | Unnamed: 4 | |
---|---|---|---|---|---|
0 | ผลผลิตทุเรียนแยกตามจังหวัด ปี 2562 | NaN | NaN | NaN | NaN |
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
2 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
3 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
4 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
จะเห็นว่าหัวตารางยังไม่เป็นระเบียบ เช่น ยังมี variable (จังหวัด, ผลผลิต(ตัน), สัดส่วน, ...) ปนอยู่ในส่วนของข้อมูล โดยเราจะแก้ไขด้วยการกำหนดให้แถวที่ 1 (df.loc[1]
) เป็นหัวตาราง (df.columns
) แทน
df.columns = df.loc[1]
df.head()
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
---|---|---|---|---|---|
0 | ผลผลิตทุเรียนแยกตามจังหวัด ปี 2562 | NaN | NaN | NaN | NaN |
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
2 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
3 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
4 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
จะเห็นว่าหัวตารางกลายเป็น (จังหวัด, ผลผลิต(ตัน), สัดส่วน, ...) แล้ว
ต่อไปจะดูท้ายตารางว่ามีปัญหาด้วยหรือไม่
df.tail(5)
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
---|---|---|---|---|---|
29 | นครราชสีมา | 188 | 0.0002 | 499 | 376.75 |
30 | อุบลราชธานี | 185 | 0.0002 | 270 | 685.19 |
31 | ชลบุรี | 156 | 0.0002 | 216 | 722.22 |
32 | นนทบุรี | 8 | 0 | 114 | 70.18 |
33 | กาฬสินธุ์ | 3 | 0 | 3 | 1000 |
ท้ายตารางไม่มีปัญหาอะไร สามารถเลือกข้อมูล (slicing) เริ่มตั้งแต่แถวที่ 2 ได้เลย
df.loc[2:]
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
---|---|---|---|---|---|
2 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
3 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
4 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
5 | ตราด | 48158 | 0.0503 | 26133 | 1842.8 |
6 | สุราษฎร์ธานี | 47550 | 0.0497 | 39039 | 1218.01 |
7 | นครศรีธรรมราช | 45632 | 0.0477 | 44958 | 1014.99 |
8 | ยะลา | 39615 | 0.0414 | 48018 | 825 |
9 | อุตรดิตถ์ | 31086 | 0.0325 | 35405 | 878.01 |
10 | ระนอง | 26522 | 0.0277 | 30948 | 856.99 |
11 | นราธิวาส | 16968 | 0.0177 | 25709 | 660 |
12 | สงขลา | 11462 | 0.012 | 14382 | 796.97 |
13 | สุโขทัย | 4766 | 0.005 | 6142 | 775.97 |
14 | ศรีสะเกษ | 4108 | 0.0043 | 2953 | 1391.13 |
15 | ปัตตานี | 4031 | 0.0042 | 7059 | 571.04 |
16 | พังงา | 3986 | 0.0042 | 6161 | 646.97 |
17 | ประจวบคีรีขันธ์ | 2862 | 0.003 | 4383 | 652.98 |
18 | พัทลุง | 2018 | 0.0021 | 3346 | 603.11 |
19 | ปราจีนบุรี | 1274 | 0.0013 | 1577 | 807.86 |
20 | ตรัง | 1198 | 0.0013 | 2080 | 575.96 |
21 | ภูเก็ต | 912 | 0.001 | 2258 | 403.9 |
22 | กระบี่ | 904 | 0.0009 | 2194 | 412.03 |
23 | สตูล | 773 | 0.0008 | 1249 | 618.9 |
24 | กาญจนบุรี | 522 | 0.0005 | 1095 | 476.71 |
25 | พิษณุโลก | 452 | 0.0005 | 864 | 523.15 |
26 | นครนายก | 424 | 0.0004 | 454 | 933.92 |
27 | เพชรบุรี | 396 | 0.0004 | 656 | 603.66 |
28 | แพร่ | 297 | 0.0003 | 673 | 441.31 |
29 | นครราชสีมา | 188 | 0.0002 | 499 | 376.75 |
30 | อุบลราชธานี | 185 | 0.0002 | 270 | 685.19 |
31 | ชลบุรี | 156 | 0.0002 | 216 | 722.22 |
32 | นนทบุรี | 8 | 0 | 114 | 70.18 |
33 | กาฬสินธุ์ | 3 | 0 | 3 | 1000 |
กำหนดให้ df.loc[2:] เป็นตัวแปรใหม่เพื่อความสะดวกได้เช่นกัน
df2 = df.loc[2:]
df2.head()
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
---|---|---|---|---|---|
2 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
3 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
4 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
5 | ตราด | 48158 | 0.0503 | 26133 | 1842.8 |
6 | สุราษฎร์ธานี | 47550 | 0.0497 | 39039 | 1218.01 |
จะเห็นว่าหลังจากการทำ slicing แล้ว index ไม่ได้เริ่มที่ 0
เราสามารถใช้คำสั่ง reset_index()
เพื่อให้ index เริ่มต้นที่ 0 ได้ โดยให้เป็น df3
df3 = df2.reset_index()
df3.head()
1 | index | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
---|---|---|---|---|---|---|
0 | 2 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
1 | 3 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
2 | 4 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
3 | 5 | ตราด | 48158 | 0.0503 | 26133 | 1842.8 |
4 | 6 | สุราษฎร์ธานี | 47550 | 0.0497 | 39039 | 1218.01 |
เราสามารถลบคอลัมน์ index
เก่าทิ้งได้ด้วยคำสั่ง del
del df3["index"]
df3.head()
1 | จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) |
---|---|---|---|---|---|
0 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
1 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
2 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
3 | ตราด | 48158 | 0.0503 | 26133 | 1842.8 |
4 | สุราษฎร์ธานี | 47550 | 0.0497 | 39039 | 1218.01 |
สุดท้ายนี้ เราสามารถลบเลข 1
ที่ติดอยู่ในหัวตารางเราจากการที่เราเลือกข้อมูลแถวที่ 1
มาเป็นหัวตารางได้ด้วยการกำหนด df3.columns.name
ให้เป็น None
df3.columns.name = None
df3.head()
จังหวัด | ผลผลิต(ตัน) | สัดส่วน | เนื้อที่เก็บเกี่ยว(ไร่) | ผลผลิตต่อเนื้อที่เก็บเกี่ยว(กก.) | |
---|---|---|---|---|---|
0 | จันทบุรี | 339292 | 0.3547 | 190728 | 1778.93 |
1 | ชุมพร | 212764 | 0.2224 | 157837 | 1348 |
2 | ระยอง | 108093 | 0.113 | 64469 | 1676.67 |
3 | ตราด | 48158 | 0.0503 | 26133 | 1842.8 |
4 | สุราษฎร์ธานี | 47550 | 0.0497 | 39039 | 1218.01 |
ให้นักเรียนสุ่มหาชุดข้อมูลจาก https://data.go.th/dataset ที่มีปัญหาเกี่ยวกับรูปแบบของข้อมูล แล้วอธิบายว่าจะจัดการกับปัญหาอย่างไร
ตัวอย่างข้อมูลที่มีปัญหา เช่น ข้อมูลผลผลิตการเกษตร มลพิษสัตว์น้ำ ข้อมูลโรงงาน
2) การจัดการค่า
2.1) NaN คืออะไร และวิธีการใช้งาน dropna, isnull
เริ่มด้วยการอ่านข้อมูลสนามกีฬาในประเทศไทย https://data.go.th/dataset/stadium
df = pd.read_excel(
"https://github.com/tj-14/mirror.data.go.th/blob/main/data/stadium_1-jul-2020.xlsx?raw=true",
engine='openpyxl'
)
df.head()
OBJECTID | NAME_LABEL | SUPPORT | ADDRESS | TIME_ | PROV_NAMT | AMP_NAMT | TAM_NAMT | MOO | LATITUDE | ... | ADDRESS_SUPPORT | ACCEPT_USER | REGULATION | TRANSPORT | FIELD_EQUIPMENT | SPORT_EQUIPMENT | ILLUMINATION | UNDER_STADIUM | UNDER_STADIUM_NAME | UPDATE_DATE | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 51556 | สระกำแพงน้อย (สระว่ายนำ้ 25 เมตร ) | NaN | NaN | วันจันทร์ - วันศุกร์ เปิดบริการเวลา 08.30 น. &... | NaN | NaN | NaN | NaN | 15.100386 | ... | NaN | NaN | NaN | NaN | 1. โฟม 20 ชิ้น | 1. โฟม 20 ชิ้น | มีการติดตั้งสปอร์คไลท์ภายในสระว่ายน้ำ | 51555.0 | ศรีนครลำดวน | 30 มิ.ย. 2020 15.01.12.000000000 |
1 | 51550 | ศูนย์วิทยาศาสตร์การกีฬา (ฟิตเนส) | NaN | NaN | วันจันทร์ - ศุกร์ เวลา 09.00-18.00 น. หยุดวันเ... | NaN | NaN | NaN | NaN | 13.409439 | ... | NaN | NaN | NaN | NaN | เครื่องออกกำลังกายแบบ Station | เครื่องออกกำลังกายแบบ Free Weigth | หลอดไฟนีออนทั้งอาคาร | 18199.0 | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตชลบุรี | 29 มิ.ย. 2020 14.18.56.000000000 |
2 | 51542 | สนามกีฬาฟุตบอลหญ้าเทียม 2 | NaN | NaN | 05.30 - 18.30 | NaN | NaN | NaN | NaN | 13.412926 | ... | NaN | NaN | NaN | NaN | - ที่นั่งสำหรับนักกีฬา<br> - ประตู | ลูกฟุตบอล | ไม่มี | 51501.0 | โรงเรียนกีฬาจังหวัดชลบุรี | 29 มิ.ย. 2020 12.33.59.000000000 |
3 | 51541 | สนามฝึกซ้อมกีฬายูโด | NaN | NaN | 05.30 - 20.00 | NaN | NaN | NaN | NaN | 13.412833 | ... | NaN | NaN | NaN | NaN | NaN | ไม่มีี | มี | 51501.0 | โรงเรียนกีฬาจังหวัดชลบุรี | 29 มิ.ย. 2020 12.36.05.000000000 |
4 | 51540 | โรงฝึกกีฬายกน้ำหนัก | NaN | NaN | 05.30 - 19.00 | NaN | NaN | NaN | NaN | 13.412833 | ... | NaN | NaN | NaN | NaN | NaN | NaN | มี | 51501.0 | โรงเรียนกีฬาจังหวัดชลบุรี | 29 มิ.ย. 2020 12.38.34.000000000 |
5 rows × 30 columns
เราสามารถดูข้อมูลเบื้องต้นด้วย df.info()
อีกครั้ง
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 44188 entries, 0 to 44187
Data columns (total 30 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 OBJECTID 44188 non-null int64
1 NAME_LABEL 44188 non-null object
2 SUPPORT 43029 non-null object
3 ADDRESS 43354 non-null object
4 TIME_ 8603 non-null object
5 PROV_NAMT 44138 non-null object
6 AMP_NAMT 44138 non-null object
7 TAM_NAMT 44138 non-null object
8 MOO 9762 non-null object
9 LATITUDE 32097 non-null float64
10 LONGITUDE 32071 non-null float64
11 SUPPORT_FLAG 36188 non-null float64
12 TELEPHONE 20166 non-null object
13 EMAIL 6804 non-null object
14 AREA_SIZE1 6626 non-null float64
15 AREA_SIZE2 3110 non-null float64
16 AREA_SIZE3 2679 non-null float64
17 AREA_SIZE_TEXT 35 non-null float64
18 POST_NO 35 non-null object
19 BUILDING_BY 26 non-null object
20 ADDRESS_SUPPORT 14 non-null object
21 ACCEPT_USER 21 non-null object
22 REGULATION 10 non-null object
23 TRANSPORT 42 non-null object
24 FIELD_EQUIPMENT 32 non-null object
25 SPORT_EQUIPMENT 32 non-null object
26 ILLUMINATION 37 non-null object
27 UNDER_STADIUM 20613 non-null float64
28 UNDER_STADIUM_NAME 20599 non-null object
29 UPDATE_DATE 33496 non-null object
dtypes: float64(8), int64(1), object(21)
memory usage: 10.1+ MB
จะเห็นได้ว่านอกจาก Dtype
แล้ว คำสั่งนี้ยังบอกด้วยว่าค่า Non-Null Count
เป็นเท่าไร ซึ่งจากตารางจะเห็นได้ว่าคอลัมน์อย่าง SUPPORT
จะมีข้อมูลเป็น NaN
(Not a Number) ซึ่งเป็น Null หรือหมายความว่าช่องนั้นไม่มีข้อมูลนั่นเอง
SUPPORT
มีค่า null เป็นจำนวนเท่าไร
OBJECTID
มี Dtype เป็นอะไรnull | |
object | |
int64 | |
float64 |
LATITUDE
มี Dtype เป็นอะไรnull | |
object | |
int64 | |
float64 |
เราสามารถลบแถวที่เป็น NaN
ทิ้งได้ด้วยคำสั่ง dropna
NaN คือช่องที่ไม่ทราบค่า (missing data)
df.dropna().head()
OBJECTID | NAME_LABEL | SUPPORT | ADDRESS | TIME_ | PROV_NAMT | AMP_NAMT | TAM_NAMT | MOO | LATITUDE | ... | ADDRESS_SUPPORT | ACCEPT_USER | REGULATION | TRANSPORT | FIELD_EQUIPMENT | SPORT_EQUIPMENT | ILLUMINATION | UNDER_STADIUM | UNDER_STADIUM_NAME | UPDATE_DATE |
---|
0 rows × 30 columns
แต่ถ้าเราใช้คำสั่ง dropna
เฉย ๆ แล้ว หากแถวหนึ่งมี NaN
อยู่ จะถูกลบทันที ซึ่งถูกลบหมดนั้นหมายความว่าทุกแถวในข้อมูลมี NaN
อย่างน้อยหนึ่งช่อง
เราสามารถเลือก dropna
โดยตรวจสอบ NaN
จากบางคอลัมน์ได้ด้วยการระบุ parameter subset
ในคำสั่งด้วย
df.dropna(subset=["SUPPORT"]).head()
OBJECTID | NAME_LABEL | SUPPORT | ADDRESS | TIME_ | PROV_NAMT | AMP_NAMT | TAM_NAMT | MOO | LATITUDE | ... | ADDRESS_SUPPORT | ACCEPT_USER | REGULATION | TRANSPORT | FIELD_EQUIPMENT | SPORT_EQUIPMENT | ILLUMINATION | UNDER_STADIUM | UNDER_STADIUM_NAME | UPDATE_DATE | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
15 | 51525 | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตยะลา | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตยะลา | 129 ถ.เทศบาล3 | NaN | ยะลา | เมืองยะลา | สะเตง | NaN | 0.000000 | ... | 129 ถ.เทศบาล3 ต.สะเตง อ.เมือง จ.ยะลา | NaN | NaN | - | NaN | NaN | NaN | NaN | NaN | 26 มิ.ย. 2020 15.25.11.000000000 |
21 | 51517 | มหาวิทยาลัยการกีฬาแห่งชาติวิทยาเขตเชียงใหม่ | มหาวิทยาลัยการกีฬาแห่งชาติวิทยาเขตเชียงใหม่ | 68/1 ถนนสนามกีฬา ตำบลศรีภูมิ อำเภอเมือง จังหวั... | NaN | เชียงใหม่ | เมืองเชียงใหม่ | ศรีภูมิ | NaN | 0.000000 | ... | 68/1 ถนนสนามกีฬา ตำบลศรีภูมิ อำเภอเมือง จังหวั... | NaN | NaN | - | NaN | NaN | NaN | NaN | NaN | 26 มิ.ย. 2020 10.17.20.000000000 |
26 | 51512 | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตสมุทรสาคร | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตสมุทรสาคร | 137 หมู่ 3 | NaN | สมุทรสาคร | เมืองสมุทรสาคร | บางหญ้าแพรก | NaN | 13.540169 | ... | 137 หมู่ 3 ตำบลบางหญ้าแพรก อำเภอเมือง จังหวัดส... | NaN | NaN | รถยนต์ส่วนตัว รถจักรยานยนต์ส่วนตัว รถจักรยานยน... | NaN | NaN | NaN | NaN | NaN | 25 มิ.ย. 2020 11.18.16.000000000 |
29 | 51509 | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตลำปาง | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตลำปาง | 398 หมู่ 15 | NaN | ลำปาง | เมืองลำปาง | บ่อแฮ้ว | NaN | 0.000000 | ... | NaN | NaN | NaN | - | NaN | NaN | NaN | NaN | NaN | 26 มิ.ย. 2020 15.24.06.000000000 |
36 | 51502 | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตสุพรรณบุรี | มหาลัยการกีฬาแห่งชาติ วิทยาเขตสุพรรณบุรี | 1หมู่4 ถนน มาลัยแมน | NaN | สุพรรณบุรี | เมืองสุพรรณบุรี | รั้วใหญ่ | NaN | 0.000000 | ... | NaN | NaN | NaN | - | NaN | NaN | NaN | NaN | NaN | 25 มิ.ย. 2020 11.09.06.000000000 |
5 rows × 30 columns
จะเห็นได้ว่าตารางที่ได้ออกมานั้นไม่มี NaN
ในคอลัมน์ SUPPORT
อีกต่อไป
df.dropna(subset=["SUPPORT"]).info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 43029 entries, 15 to 44187
Data columns (total 30 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 OBJECTID 43029 non-null int64
1 NAME_LABEL 43029 non-null object
2 SUPPORT 43029 non-null object
3 ADDRESS 42242 non-null object
4 TIME_ 8559 non-null object
5 PROV_NAMT 43026 non-null object
6 AMP_NAMT 43026 non-null object
7 TAM_NAMT 43026 non-null object
8 MOO 9738 non-null object
9 LATITUDE 31967 non-null float64
10 LONGITUDE 31943 non-null float64
11 SUPPORT_FLAG 35079 non-null float64
12 TELEPHONE 20151 non-null object
13 EMAIL 6794 non-null object
14 AREA_SIZE1 6624 non-null float64
15 AREA_SIZE2 3110 non-null float64
16 AREA_SIZE3 2679 non-null float64
17 AREA_SIZE_TEXT 13 non-null float64
18 POST_NO 25 non-null object
19 BUILDING_BY 21 non-null object
20 ADDRESS_SUPPORT 14 non-null object
21 ACCEPT_USER 17 non-null object
22 REGULATION 10 non-null object
23 TRANSPORT 34 non-null object
24 FIELD_EQUIPMENT 11 non-null object
25 SPORT_EQUIPMENT 11 non-null object
26 ILLUMINATION 12 non-null object
27 UNDER_STADIUM 20528 non-null float64
28 UNDER_STADIUM_NAME 20515 non-null object
29 UPDATE_DATE 33353 non-null object
dtypes: float64(8), int64(1), object(21)
memory usage: 10.2+ MB
จะเห็นได้ว่าหลังจากเช็คด้วย info
แล้วคอลัมน์ SUPPORT
มี 43029
non-null count ซึ่งเท่ากับจำนวน 43029
entries
สำหรับกรณีที่เราอยากรู้ว่าหน้าตาของแถวที่คอลัมน์ SUPPORT
เป็น NaN
มีหน้าตาอย่างไร เราสามารถใช้คำสั่ง isnull
เข้ามาช่วยได้
df["SUPPORT"].isnull()
0 True
1 True
2 True
3 True
4 True
...
44183 False
44184 False
44185 False
44186 False
44187 False
Name: SUPPORT, Length: 44188, dtype: bool
โดยคำสั่ง isnull
จะคืนค่าเป็นค่าความจริง (boolean) ว่าแถวนั้น ๆ มีค่าเป็น NaN
หรือไม่
และเราสามารถใช้ค่าความจริงนี้มาทำ masking ได้
df[df["SUPPORT"].isnull()].head()
OBJECTID | NAME_LABEL | SUPPORT | ADDRESS | TIME_ | PROV_NAMT | AMP_NAMT | TAM_NAMT | MOO | LATITUDE | ... | ADDRESS_SUPPORT | ACCEPT_USER | REGULATION | TRANSPORT | FIELD_EQUIPMENT | SPORT_EQUIPMENT | ILLUMINATION | UNDER_STADIUM | UNDER_STADIUM_NAME | UPDATE_DATE | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 51556 | สระกำแพงน้อย (สระว่ายนำ้ 25 เมตร ) | NaN | NaN | วันจันทร์ - วันศุกร์ เปิดบริการเวลา 08.30 น. &... | NaN | NaN | NaN | NaN | 15.100386 | ... | NaN | NaN | NaN | NaN | 1. โฟม 20 ชิ้น | 1. โฟม 20 ชิ้น | มีการติดตั้งสปอร์คไลท์ภายในสระว่ายน้ำ | 51555.0 | ศรีนครลำดวน | 30 มิ.ย. 2020 15.01.12.000000000 |
1 | 51550 | ศูนย์วิทยาศาสตร์การกีฬา (ฟิตเนส) | NaN | NaN | วันจันทร์ - ศุกร์ เวลา 09.00-18.00 น. หยุดวันเ... | NaN | NaN | NaN | NaN | 13.409439 | ... | NaN | NaN | NaN | NaN | เครื่องออกกำลังกายแบบ Station | เครื่องออกกำลังกายแบบ Free Weigth | หลอดไฟนีออนทั้งอาคาร | 18199.0 | มหาวิทยาลัยการกีฬาแห่งชาติ วิทยาเขตชลบุรี | 29 มิ.ย. 2020 14.18.56.000000000 |
2 | 51542 | สนามกีฬาฟุตบอลหญ้าเทียม 2 | NaN | NaN | 05.30 - 18.30 | NaN | NaN | NaN | NaN | 13.412926 | ... | NaN | NaN | NaN | NaN | - ที่นั่งสำหรับนักกีฬา<br> - ประตู | ลูกฟุตบอล | ไม่มี | 51501.0 | โรงเรียนกีฬาจังหวัดชลบุรี | 29 มิ.ย. 2020 12.33.59.000000000 |
3 | 51541 | สนามฝึกซ้อมกีฬายูโด | NaN | NaN | 05.30 - 20.00 | NaN | NaN | NaN | NaN | 13.412833 | ... | NaN | NaN | NaN | NaN | NaN | ไม่มีี | มี | 51501.0 | โรงเรียนกีฬาจังหวัดชลบุรี | 29 มิ.ย. 2020 12.36.05.000000000 |
4 | 51540 | โรงฝึกกีฬายกน้ำหนัก | NaN | NaN | 05.30 - 19.00 | NaN | NaN | NaN | NaN | 13.412833 | ... | NaN | NaN | NaN | NaN | NaN | NaN | มี | 51501.0 | โรงเรียนกีฬาจังหวัดชลบุรี | 29 มิ.ย. 2020 12.38.34.000000000 |
5 rows × 30 columns
จะทำให้เราได้เห็นว่าหน้าตาของแถวที่ SUPPORT
เป็น NaN
นั้นเป็นอย่างไร
2.2) Non-NaN missing data
เริ่มด้วยการอ่านข้อมูลโรงงาน 101-105-106 https://data.go.th/dataset/item_2d831f97-991a-44e0-ac34-d37f01c81e0b
df = pd.read_csv(
"https://github.com/tj-14/mirror.data.go.th/raw/main/data/101-105-106-1.csv",
encoding="ISO-8859-11"
)
df.head()
ลำดับ | เลขทะเบียนโรงงาน | ชื่อโรงงาน | ประกอบกิจการ | เลขที่ | หมู่ | ซอย | ถนน | ตำบล | อำเภอ | จังหวัด | ไปรษณีย์ | โทรศัพท์ | เงินทุนรวม | คนงาน | แรงม้า | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3-101-1/38 | บริษัท โอสถสภา จำกัด | บำบัดน้ำทิ้งรวม ได้ 4,800 ลูกบาศก์เมตร/วัน | เลขที่ 348 | NaN | NaN | รามคำแหง | หัวหมาก | บางกะปิ | กรุงเทพมหานคร | 10240.0 | 3511123-24 | 20000000.0 | 5 | 270.68 |
1 | 2 | 3-101-1/40 | บริษัท ซีพีเอฟ (ประเทศไทย) จำกัด (มหาชน) | โรงงานปรับคุณภาพของเสียรวม | เลขที่ 48 | 9 | - | สุวินทวงศ์ | แสนแสบ | มีนบุรี | กรุงเทพมหานคร | 10510.0 | 989-4050-62 | 43100000.0 | 10 | 356.00 |
2 | 3 | 3-101-1/45 | บริษัท มหาจักรออโตพาร์ท จำกัด | ปรับคุณภาพน้ำเสียรวม | เลขที่ 67/16 | 5 | - | เชื่อมสัมพันธ์ | โคกแฝด | หนองจอก | กรุงเทพมหานคร | 10530.0 | 02-543-1212 | 0.0 | 6 | 109.40 |
3 | 4 | 3-101-1/47 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้... | ปรับคุณภาพของเสียรวม | เลขที่ 68/39 | 3 | แสมดำ 17 | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | NaN | 127500000.0 | 23 | 862.20 |
4 | 5 | 3-101-2/38 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้... | ปรับคุณภาพของเสียรวม คัดแยกวัสดุที่ไม่ใช้แล้ว ... | เลขที่ 68/39 | 3 | วัดแสมดำ | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | 4153728 | 5000000.0 | 82 | 439.00 |
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1967 entries, 0 to 1966
Data columns (total 16 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ลำดับ 1967 non-null int64
1 เลขทะเบียนโรงงาน 1967 non-null object
2 ชื่อโรงงาน 1967 non-null object
3 ประกอบกิจการ 1967 non-null object
4 เลขที่ 1967 non-null object
5 หมู่ 1893 non-null object
6 ซอย 1316 non-null object
7 ถนน 1523 non-null object
8 ตำบล 1967 non-null object
9 อำเภอ 1967 non-null object
10 จังหวัด 1967 non-null object
11 ไปรษณีย์ 1964 non-null float64
12 โทรศัพท์ 821 non-null object
13 เงินทุนรวม 1964 non-null float64
14 คนงาน 1967 non-null int64
15 แรงม้า 1965 non-null float64
dtypes: float64(3), int64(2), object(11)
memory usage: 246.0+ KB
ซอย
มีค่า null เป็นจำนวนเท่าไร
ซอย
เป็นอะไร
จะเห็นได้ว่าในตารางจะมีทั้งข้อมูลที่เป็น NaN
และ -
เช่นในคอลัมน์ ซอย
ซึ่งเป็น missing data ทั้งสองกรณี แต่ -
จะถูกนับเป็น non-null
ซึ่งอาจทำให้เราเข้าใจผิดได้
เราสามารถระบุ parameter na_values
ในฟังก์ชัน read_csv
ได้ให้ pandas
เข้าใจว่าเราต้องการให้ข้อมูลอะไรเป็น NaN
เพิ่มเติม
df = pd.read_csv(
"https://github.com/tj-14/mirror.data.go.th/raw/main/data/101-105-106-1.csv",
encoding="ISO-8859-11",
na_values=["-"]
)
df.head()
ลำดับ | เลขทะเบียนโรงงาน | ชื่อโรงงาน | ประกอบกิจการ | เลขที่ | หมู่ | ซอย | ถนน | ตำบล | อำเภอ | จังหวัด | ไปรษณีย์ | โทรศัพท์ | เงินทุนรวม | คนงาน | แรงม้า | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3-101-1/38 | บริษัท โอสถสภา จำกัด | บำบัดน้ำทิ้งรวม ได้ 4,800 ลูกบาศก์เมตร/วัน | เลขที่ 348 | NaN | NaN | รามคำแหง | หัวหมาก | บางกะปิ | กรุงเทพมหานคร | 10240.0 | 3511123-24 | 20000000.0 | 5 | 270.68 |
1 | 2 | 3-101-1/40 | บริษัท ซีพีเอฟ (ประเทศไทย) จำกัด (มหาชน) | โรงงานปรับคุณภาพของเสียรวม | เลขที่ 48 | 9 | NaN | สุวินทวงศ์ | แสนแสบ | มีนบุรี | กรุงเทพมหานคร | 10510.0 | 989-4050-62 | 43100000.0 | 10 | 356.00 |
2 | 3 | 3-101-1/45 | บริษัท มหาจักรออโตพาร์ท จำกัด | ปรับคุณภาพน้ำเสียรวม | เลขที่ 67/16 | 5 | NaN | เชื่อมสัมพันธ์ | โคกแฝด | หนองจอก | กรุงเทพมหานคร | 10530.0 | 02-543-1212 | 0.0 | 6 | 109.40 |
3 | 4 | 3-101-1/47 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้... | ปรับคุณภาพของเสียรวม | เลขที่ 68/39 | 3 | แสมดำ 17 | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | NaN | 127500000.0 | 23 | 862.20 |
4 | 5 | 3-101-2/38 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้... | ปรับคุณภาพของเสียรวม คัดแยกวัสดุที่ไม่ใช้แล้ว ... | เลขที่ 68/39 | 3 | วัดแสมดำ | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | 4153728 | 5000000.0 | 82 | 439.00 |
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1967 entries, 0 to 1966
Data columns (total 16 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ลำดับ 1967 non-null int64
1 เลขทะเบียนโรงงาน 1967 non-null object
2 ชื่อโรงงาน 1967 non-null object
3 ประกอบกิจการ 1967 non-null object
4 เลขที่ 1967 non-null object
5 หมู่ 1880 non-null object
6 ซอย 479 non-null object
7 ถนน 974 non-null object
8 ตำบล 1967 non-null object
9 อำเภอ 1967 non-null object
10 จังหวัด 1967 non-null object
11 ไปรษณีย์ 1964 non-null float64
12 โทรศัพท์ 749 non-null object
13 เงินทุนรวม 1964 non-null float64
14 คนงาน 1967 non-null int64
15 แรงม้า 1965 non-null float64
dtypes: float64(3), int64(2), object(11)
memory usage: 246.0+ KB
ซอย
มีค่า null เป็นจำนวนเท่าไร
หลังจากระบุ na_values
เพิ่มแล้วจะเห็นได้ว่า non-null
ของ ซอย
นั้นจริง ๆ มีเพียง 479
ค่าเท่านั้นจากเดิมที่เป็น 1316
ที่คิดว่า -
เป็น non-null
2.3) กำหนด index
สามารถใช้คอลัมน์ ลำดับ
เป็น index ได้ด้วยการกำหนด index_col=0
df = pd.read_csv(
"https://github.com/tj-14/mirror.data.go.th/raw/main/data/101-105-106-1.csv",
encoding="ISO-8859-11",
na_values=["-"],
index_col=0
)
df.head()
เลขทะเบียนโรงงาน | ชื่อโรงงาน | ประกอบกิจการ | เลขที่ | หมู่ | ซอย | ถนน | ตำบล | อำเภอ | จังหวัด | ไปรษณีย์ | โทรศัพท์ | เงินทุนรวม | คนงาน | แรงม้า | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ลำดับ | |||||||||||||||
1 | 3-101-1/38 | บริษัท โอสถสภา จำกัด | บำบัดน้ำทิ้งรวม ได้ 4,800 ลูกบาศก์เมตร/วัน | เลขที่ 348 | NaN | NaN | รามคำแหง | หัวหมาก | บางกะปิ | กรุงเทพมหานคร | 10240.0 | 3511123-24 | 20000000.0 | 5 | 270.68 |
2 | 3-101-1/40 | บริษัท ซีพีเอฟ (ประเทศไทย) จำกัด (มหาชน) | โรงงานปรับคุณภาพของเสียรวม | เลขที่ 48 | 9 | NaN | สุวินทวงศ์ | แสนแสบ | มีนบุรี | กรุงเทพมหานคร | 10510.0 | 989-4050-62 | 43100000.0 | 10 | 356.00 |
3 | 3-101-1/45 | บริษัท มหาจักรออโตพาร์ท จำกัด | ปรับคุณภาพน้ำเสียรวม | เลขที่ 67/16 | 5 | NaN | เชื่อมสัมพันธ์ | โคกแฝด | หนองจอก | กรุงเทพมหานคร | 10530.0 | 02-543-1212 | 0.0 | 6 | 109.40 |
4 | 3-101-1/47 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้... | ปรับคุณภาพของเสียรวม | เลขที่ 68/39 | 3 | แสมดำ 17 | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | NaN | 127500000.0 | 23 | 862.20 |
5 | 3-101-2/38 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้... | ปรับคุณภาพของเสียรวม คัดแยกวัสดุที่ไม่ใช้แล้ว ... | เลขที่ 68/39 | 3 | วัดแสมดำ | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | 4153728 | 5000000.0 | 82 | 439.00 |
ลำดับ
ซอย
เป็นอะไร
2.4) การจัดการข้อมูล และการคำนวณค่าจากหลายคอลัมน์
ทั้งนี้อาจจะสังเกตเห็นว่าคอลัมน์ ไปรษณีย์
เป็นจำนวนจริง แต่ควรจะเป็นข้อความ (string) มากกว่า เราสามารถแก้ได้ด้วยคำสั่ง astype
แต่ไม่สามารถแปลงได้ตรง ๆ เนื่องจากว่าคอลัมน์นี้มี NaN
ผสม จึงต้อง dropna
ก่อน แล้วแปลงเป็น int
เพื่อลบ .0
แล้วจึงแปลงเป็น str
df["ไปรษณีย์"].dropna().astype(int).astype(str)
ลำดับ
1 10240
2 10510
3 10530
4 10150
5 10150
...
1963 92110
1964 92140
1965 92000
1966 94170
1967 94120
Name: ไปรษณีย์, Length: 1964, dtype: object
นอกจากนี้ เรายังสามารถนำค่าของคอลัมน์หลายคอลัมน์มาทำการคำนวณได้ด้วย (คล้ายกับ NumPy Array)
df["เงินทุนรวม"] / df["คนงาน"]
ลำดับ
1 4.000000e+06
2 4.310000e+06
3 0.000000e+00
4 5.543478e+06
5 6.097561e+04
...
1963 6.000000e+05
1964 2.456140e+06
1965 1.466000e+06
1966 1.962500e+06
1967 1.370000e+05
Length: 1967, dtype: float64
df["แรงม้า"] / df["คนงาน"]
ลำดับ
1 54.136000
2 35.600000
3 18.233333
4 37.486957
5 5.353659
...
1963 29.666667
1964 70.246667
1965 7.630000
1966 37.661250
1967 2.275000
Length: 1967, dtype: float64
โดยเราสามารถกำหนดค่าคอลัมน์ใหม่จากการคำนวณคอลัมน์เดิมได้ด้วย
df["เงินทุนรวมต่อคนงาน"] = df["เงินทุนรวม"] / df["คนงาน"]
df.head()
เลขทะเบียนโรงงาน | ชื่อโรงงาน | ประกอบกิจการ | เลขที่ | หมู่ | ซอย | ถนน | ตำบล | อำเภอ | จังหวัด | ไปรษณีย์ | โทรศัพท์ | เงินทุนรวม | คนงาน | แรงม้า | เงินทุนรวมต่อคนงาน | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ลำดับ | ||||||||||||||||
1 | 3-101-1/38 | บริษัท โอสถสภา จำกัด | บำบัดน้ำทิ้งรวม\xa0ได้\xa04,800\xa0ลูกบาศก์เมตร/วัน | เลขที่ 348 | NaN | NaN | รามคำแหง | หัวหมาก | บางกะปิ | กรุงเทพมหานคร | 10240.0 | 3511123-24 | 20000000.0 | 5 | 270.68 | 4.000000e+06 |
2 | 3-101-1/40 | บริษัท ซีพีเอฟ (ประเทศไทย) จำกัด (มหาชน) | โรงงานปรับคุณภาพของเสียรวม | เลขที่ 48 | 9 | NaN | สุวินทวงศ์ | แสนแสบ | มีนบุรี | กรุงเทพมหานคร | 10510.0 | 989-4050-62 | 43100000.0 | 10 | 356.00 | 4.310000e+06 |
3 | 3-101-1/45 | บริษัท มหาจักรออโตพาร์ท จำกัด | ปรับคุณภาพน้ำเสียรวม | เลขที่ 67/16 | 5 | NaN | เชื่อมสัมพันธ์ | โคกแฝด | หนองจอก | กรุงเทพมหานคร | 10530.0 | 02-543-1212 | 0.0 | 6 | 109.40 | 0.000000e+00 |
4 | 3-101-1/47 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้อม จำกัด (มหาชน) | ปรับคุณภาพของเสียรวม | เลขที่ 68/39 | 3 | แสมดำ 17 | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | NaN | 127500000.0 | 23 | 862.20 | 5.543478e+06 |
5 | 3-101-2/38 | บริษัท บริหารและพัฒนาเพื่อการอนุรักษ์สิ่งแวดล้อม จำกัด | ปรับคุณภาพของเสียรวม คัดแยกวัสดุที่ไม่ใช้แล้ว ตามประกาศกระทรวงอุตสาหกรรม ฉบับที่ 1 (พ.ศ.2541) และประกอบกิจการทำวัสดุและเชื้อเพลิงผสมจากของเสียประเภทต่าง ๆ (BLENDING) | เลขที่ 68/39 | 3 | วัดแสมดำ | พระรามที่ 2 | แสมดำ | บางขุนเทียน | กรุงเทพมหานคร | 10150.0 | 4153728 | 5000000.0 | 82 | 439.00 | 6.097561e+04 |
จะเห็นว่ามีคอลัมน์ เงินทุนรวมต่อคนงาน
เกิดขึ้นที่ด้านขวาสุดของตาราง
อ.จะสุ่มให้นักเรียนสร้างคอลัมน์ใหม่จากการคำนวณระหว่างสองคอลัมน์ที่มีอยู่แล้ว จากชุดข้อมูลปริมาณการใช้งานเน็ตประชารัฐ https://data.go.th/dataset/village_internet_usage
หากโหลดข้อมูลในรูปแบบ excel จะสามารถระบุ parameter sheet_name
เพื่อให้อ่านชีทที่ต้องการได้