เราได้หัดการใช้ Python อ่านข้อมูลจากไฟล์ Excel ต่างๆ, เตรียมข้อมูลให้พร้อมในการใช้งาน, ประกอบรายงานใหม่ขึ้นมา และ Export ไฟล์ลงไปที่ Directory ที่เลือกไว้ (Read -> Clean -> Join -> Export) ซึ่งในที่สุดเราได้รายงานภาพรวมธุรกิจมา 2 ชิ้นคือ 1. รายงานสรุปยอดสินค้าขายต่อวันเทียบสินค้าคงเหลือ 2. รายงานสรุปกำไรรายสินค้าต่อวันเทียบจำนวนคงเหลือ Show สำหรับ Part 1 เราได้เคลียร์ 3 ข้อนี้จบไป
ส่วนใน Part 2 เราจะมาต่อกันที่ 2 ข้อนี้กันนะครับ
สำหรับเนื้อหาครั้งนี้ ขอขอบคุณ 425degree.com ที่เอื้อเฟื้อข้อมูลเบื้องตันให้ ข้อมูลและตัวอย่างโค้ดได้ถูกดัดแปลงเพื่อให้เหมาะกับ Tutorial ในครั้งนี้ ซึ่งผมรวมไว้ที่ลิ้งนี้แล้วครับ ผู้อ่านท่านใดสนใจซื้อ เคส กระเป๋า หูฟัง เรียนเชิญที่ร้านนี้ครับ สั่งง่าย ส่งไว ได้ของชัวร์ครับ Motivationรายงานภาพรวมที่เราเพิ่งทำกันไป สามารถให้ insight เราได้หลายอย่าง แต่ก็เป็นเพียงคำตอบหนึ่งของคำถามอีกมากมายที่เหล่าพ่อค้าแม่ขายอยากจะรู้ครับ ลองคิดถึงสถานการณ์ว่ามีลูกค้ามาติดต่อซื้อของที่ร้าน หลายครั้งลูกค้าสนใจอยากรู้แค่ราคาของสินค้าหรือแค่อยากรู้ว่าที่ร้านมีสินค้าพร้อมขายไหม สำหรับเหตุการณ์ดังกล่าวคุณลูกค้า(หรือแม้แต่ตัวพ่อค้าเอง)ไม่จำเป็นต้องรู้รายละเอียดส่วนอื่นๆในร้านเลยก็ได้ ซึ่งรายงานภาพรวมที่เราทำกันไปแล้วก็มีข้อมูลมากมายหลากหลายเหลือเกิน รายงานนี้จึงอาจไม่เหมาะจะใช้ในสถานการณ์ดังกล่าวซะทีเดียว ซึ่งวันนี้เราจะเขียน Function แสดงข้อมูลเฉพาะบางส่วนจากรายงานภาพรวมกันนะครับ อีกเหตุการณ์ที่น่าสนใจคือ สมมุติว่าพ่อค้ากำลังวางแผนการตลาด / วางแผนสินค้าคงคลัง เขาอาจจะต้องการเข้าใจสถานการณ์ของยอดขายย้อนหลังตลอด 6 เดือนที่ผ่านมา ซึ่งรายงานภาพรวมของเราก็พอให้ insight ได้บ้างแต่พอมีตัวเลขเยอะมากๆเข้าก็อาจจะดูไม่ถนัดแล้วทำให้การสื่อสาร / ตัดสินใจผิดพลาดไป กรณีนี้เราจะทำ Data Visualization มาเพื่อแสดงภาพรวมที่แท้จริงและใช้เป็นไกด์ไลน์สำหรับการค้นคว้าขั้นต่อๆไปด้วยครับ เริ่มเนื้อหาตรงนี้เลยนะครับFilter Dataเราลองมาอุ่นเครื่องกันก่อนด้วยการทำความเข้าใจการ Filtering Data การทำ Filter คือการกรองข้อมูลที่เตรียมไว้เรียบร้อยแล้วมาแสดงผลเฉพาะแค่บางส่วนเพื่อให้ได้คำตอบที่ต้องการครับ ถ้าให้เปรียบเทียบก็เหมือนการร่อนทองออกจากโคลนครับผม ยกตัวอย่างว่าเราต้องการทราบกำไรรายสินค้าต่อวันเทียบจำนวนคงเหลือ แต่อยากรู้แค่ 7 วันย้อนหลังเท่านั้น เราสามารถทำได้โดยการคัดกรอง รายงานสรุปกำไรรายสินค้าต่อวันเทียบจำนวนคงเหลือที่เราสร้างไว้แล้วใน Part 1 ซึ่งโค้ดจะหน้าตาประมาณนี้ครับ
ผมขออธิบายแจกแจงโค้ดเล็กน้อยนะครับเพราะต่อไปจะใช้เทคนิคนี้บ่อยหน่อย หลายๆท่านจะได้เข้าใจเนื้อหาได้ง่ายขึ้นด้วย โค้ดด้านล่างนี้ผมใช้สำหรับสร้างชุดตัวเลขขึ้นมาครับ โดยที่ตัวเลขชุดนี้มี
3 เป็น
4 หรือ
5 หากผู้อ่านจำใน Part 1 ได้ เราเคย import pandas และ numpy เอาไว้แล้ว จังหวะจะใช้ก็ต้องตอนนี้แล้วครับผม
ส่วนโค้ดนี้ใช้เลือกชื่อของหลัก(Header)ที่ต้องการแสดงผลนะครับ โดยเป็นหลักที่เราเลือกถูกกำหนดโดยตัวเลข -3, -11,.. เป็นต้นนะครับ และที่เราไม่ใส่
6 ลงไปตรงๆเลยก็เพราะ
7 ของ pandas แกรับ input เฉพาะ
5 เท่านั้น
ซึ่ง Header ดังกล่าวก็จะใส่เข้าไปใน
9 ใช้สำหรับการคัดกรองข้อมูลที่ต้องการแสดง พร้อมกันนี้ผมขอจัดอันดับกำไรสินค้า 7 วันย้อนหลังจากมากลงไปน้อยด้วย method
0 รู้จักกับ Function (สำหรับ Beginner เท่านั้น)เราเพิ่งทำ Filtering Data ไป ทุกอย่างเรียบร้อยสวยงามยกเว้นเรื่องเดียวครับคือโค้ดมันยาวเหยียดเหลือเกิน ทำให้มีโอกาสพิมพ์ผิดและเกิด Error ได้ง่าย ดังนั้นเราควรสร้าง Function เพื่อแสดงผลลัพธ์โดยที่เป้าหมายของ Function คือทำให้แสดงผลได้ด้วยโค้ดสั้นๆ สำหรับผู้อ่านที่ยังไม่รู้จัก Function นะครับ อธิบายคร่าวๆได้ว่า Function เป็นการรวบรวมชุดคำสั่งและไปขึ้นไว้กับชื่อๆนึง โดยถ้าชื่อดังกล่าวนั้นถูกเรียกใช้งานเมื่อไร ชุดคำสั่งภายใต้ชื่อนั้นจะถูกเรียกไปด้วยครับ ลองยกตัวอย่างจากโค้ดด้านบนนะครับ method
1 เป็นคำสั่งที่ทำหน้าที่เรียงลำดับเลขให้เรา ซึ่งหากถามผมว่า
1 ใช้วิธีการอะไร ตรรกะแบบไหนในการจัดเรียงลำดับเลขให้เรา ผมคงต้องตอบว่าไม่รู้เหมือนกันเพราะชุดคำสั่งก็ถูกซ่อนอยู่ภายใต้ชื่อ
1 แต่รู้อยู่อย่างเดียวและอย่างเดียวก็พอ คือ
1 มันเรียงเลขให้เราได้จริงๆ Ok! สรุปสิ่งที่ได้เรียนรู้จาก
1 ก็คือผู้ใช้ Function ไม่จำเป็นต้องรู้รายละเอียดว่า Function นั้นทำงานยังไงแต่รู้แค่ว่ามันทำอะไรได้ก็พอ! และพอถึงจังหวะจะใช้ก็ call Function มาใช้เลยครับ method และ function มีความแตกต่างในรายละเอียดอยู่บ้าง สำหรับผู้ที่สนใจอ่านเพิ่มเติมเกี่ยวความแตกต่างระหว่าง method และ function นะครับ เชิญอ่านต่อที่ลิ้งนี้เลยครับ Function ของ python มีโครงสร้างประมาณนี้ครับผม หากโค้ดบล็อคใดๆมีย่อหน้า(indentation)อยู่ถัดเข้าไปทางขาวของย่อหน้า
6 ชุดคำสั่งดังกล่าวก็จะไปขึ้นอยู่กับ
7 นั้นๆโดยที่มี input เป็น
8 และ output เป็น
9 ครับ
ตัวอย่าง Function สำหรับ Tutorial นี้ลองสมมุติว่าพ่อค้าอยากรู้กำไรต่อวันเทียบจำนวนคงเหลือ 7 วันย้อนหลังแต่แสดงผลเฉพาะสินค้าที่มีชื่อนี้รหัสนั้น โดยพ่อค้าจะใส่ Keyword เข้าไปเป็นชื่อสินค้าหรือรหัสสินค้าก็ได้แล้วได้คำตอบออกมาเลย ซึ่ง Keyword ที่ใส่เข้าไปอาจจะใส่ตัวเล็กตัวใหญ่แบบไหนก็ได้นะครับ เราน่าจะพอเขียน Function สำหรับคัดกรองคำตอบไปประมาณนี้ครับผม
ยังจำคำสั่ง
0 ด้านบนกันได้อยู่ใช่ไหมครับ ส่วนนี้ให้ผลลัพธ์เป็น Header สำหรับการกรองข้อมูลนะครับ ใครลืมก็ย้อนไปดูด้านบน
1 คำสั่งนี้ใช้คัดกรองเฉพาะรายการที่ชื่อสินค้าตรงกับ Keyword ที่พ่อค้าใส่เข้ามานะครับ โดยที่เราจะไม่สนใจตัวเล็กตัวใหญ่ และเราข้าม Missing Value ไปด้วยเลยนะครับ ส่วน
2 จะเกี่ยวกับ Keyword ฝั่งรหัสสินค้า(เป็น index ของเราตั้งแต่ Part 1) ผู้อ่านจะพอเห็นอยู่ว่า function ที่เราสร้างขึ้นมาเป็น function ที่ซ้อนใน function อีกทีนึงหรือที่เราเรียกกันว่า Nested function นะครับ โดยผลลัพธ์สุดท้ายของ Top-level Function
3 จะเป็นผลลัพธ์ 2 function ย่อยของเรา(
4 และ
5)รวมกันครับ ซึ่งผลลัพธ์สุดท้ายจะถูกรวมออกมาโดยใช้โค้ดว่า
6 หากใครอยากรู้เพิ่มเติมเกี่ยวกับ Nested Function อ่านได้จากลิ้งนี้ครับ หากเราลองรันคำสั่ง
7 ดูจะได้คำตอบอย่างในรูปนะครับ ผู้อ่านอาจจะลองเปลี่ยน
8 เป็น
9หรือสับเปลี่ยนตัวอักษรเล็กใหญ่ดูได้ครับ ทำนองเดียวกันเราสามารถสรุปยอดสินค้าขายต่อวันเทียบสินค้าคงเหลือ 7 วันย้อนหลังแบบเจาะจงสินค้าได้โดยใช้ Function แบบครั้งก่อนได้เลยแต่แตกต่างกันที่ Function ใหม่ใช้ข้อมูลยอดขายแทนข้อมูลกำไร
ลอง call Function
0 ดูซักหน่อยโดยใช้
1 เป็น input Keyword แถมอีกสัก Function ละกัน อันนี้เอาไว้แสดงราคาขายกับสต็อก โดยที่อันไหนมีคำว่า
2 แล้วก็ไม่่ต้องโชว์ครับผม จะได้บอกลูกค้าถูกว่าของชิ้นนี้ราคาเท่าไร มีของพร้อมส่งไหม
Call
3 จะได้ผลในรูปด้านล่าง ซึ่งเห็นได้ชัดเจนว่า US347-AL-C (เลิก)Phosphorescence Glowing iPhone X Case Windu ที่เคยมีคำตอบใน
4 ไม่มีอยู่ในคำตอบของ
3 Data Visualization : “A picture is worth a thousand words”ขอย้อนกลับไปใน Part 1 ที่เราปิดงานด้วยการทำรายงานภาพรวมธุรกิจ แล้วลองเปิดไฟล์กำไรที่เรา Export ไว้ จะได้หน้าตาประมาณนี้ครับ ตัวรายงานแม้ว่าจะมีความสมบูรณ์แค่ไหน แต่ถ้ามีตัวเลขเยอะๆแบบนี้ก็ตาลายได้เหมือนกันครับ ยิ่งถ้าต้องการโฟกัสเฉพาะบาง SKU ยกตัวอย่างเช่น US347-AL เรายิ่งดูไม่ออกเลยว่าช่วงไหนขายดี ข่วงไหนยอดตก กลายเป็นว่ารายงานที่ทำออกมาเพื่อให้เห็นภาพรวมกลับไม่สามารถบรรลุวัตถุประสงค์ได้ นี้เป็นเพราะข้อมูลมีเยอะเกินไปจนสมองของเราประมวลผลไม่ทันครับ ซึ่งเราจะแก้โดยใช้ Data Visualization มาเล่าภาพรวมให้เราเข้าใจ ให้เราเห็นภาพ ซึ่งจริงๆแล้วรูป Cover ที่ผู้อ่านเห็นด้านบนก็คือผลงาน Data Visualization ที่เราจะทำกันในวันนี้แหละครับ Library สำหรับการทำ Visualization ของ Python มีให้เลือกมากมายทีเดียวครับ แต่ที่ผมเลือกใช้ในวันนี้ชื่อ bokeh ครับ เหตุผลที่ใช้คือ bokeh ไม่เสียตังครับ ฮ่าๆๆๆ นอกจากนี้ยังสามารถพล็อตแบบ interactive ด้วย ความหมายคือเราสามารถคลิกๆลากๆภายในกราฟและได้เห็นข้อมูลที่เปลี่ยนไปตาม action ของเราได้เลยครับ บอกก่อนว่าการพล็อตค่อนข้างเป็นศิลปะครับ มันไม่ตายตัว ซึ่งที่จะทำใน Tutorial นี้ก็เป็นแค่หนึ่งในสิบล้านวิธีการพล็อตสำหรับข้อมูลชุดนี้นะครับ โดยในพล็อตตัวอย่าง ผมจะทำ Punch card Plot - GitHub Style จากข้อมูลกำไรรายสินค้าต่อวันและการฟีเจอร์อื่นๆที่อยากได้สำหรับพล็อตนี้ก็คือ
สำหรับพล็อตแบบอื่นๆของ bokeh ลองเช็คดูใน Gallery ของเค้าได้ครับ import bokehOk! เรามาสร้างกราฟกันโดยเริ่มจากการเรียก Libray เข้ามาครับ แต่เราไม่ได้เอามาทั้ง bokeh นะครับแต่จะเรียกเฉพาะที่จำเป็นสำหรับ Punch card Plot - GitHub Style
จะพล็อตให้ดีก็ต้องมีข้อมูลให้พร้อมครับ ว่าแล้วก็เรียกข้อมูลกำไรรายสินค้าต่อวันย้อนหลัง 7 เดือนและตั้งชื่อข้อมูลว่า
6 นะครับ ซึ่ง
6 ก็คือ
8 ที่ตัดข้อมูลที่ไม่เกี่ยวของออกไปก่อน เช่น รายละเอียด จำนวนสินค้าคงเหลือ เป็นต้น พร้อมกันนี้เราก็ตั้งชื่อหลัก(Column) ชื่อแถว(index) และตั้งตัวแปรไว้ใช้งานในอนาคตด้วยเลย
แต่ข้อมูลชุดนี้มีปัญหานิดหน่อยครับตรงที่ bokeh ไม่เข้าใจข้อมูลที่ถูก pivot ไปแล้ว เพราะฉะนั้นเราต้องเอาตาราง pivot มาจัดเรียงให้เป็นตารางแบบก่อน pivot ครับ โชคดีที่ Pandas มีคำสั่งเฉพาะทางให้เลยทำให้เราไม่ต้องมาเรียงด้วยมือ โดยเราจะใช้ method
9 ในการจัดเรียงข้อมูล โค้ดอาจจะยาวหน่อยแต่ไม่ต้องตกใจไปครับ
อธิบายโค้ด : สำหรับชื่อหลัก, ชื่อแถวของวันที่และรหัสสินค้าเราตั้งไว้แล้วตั้งแต่โค้ดก่อนหน้านะครับ ส่วน
0 ใช้ตั้งชื่อหลักของตัวเลขกำไรในข้อมูล นอกจากนี้เรายังได้
1 เพื่อให้มีข้อมูลรายละเอียดสินค้าสำหรับแต่ละ SKU และปิดท้ายด้วยการเปลี่ยนชื่อหลัก
2 เป็น
3 เพราะว่าภาษาอังกฤษทำงานง่ายกว่าสำหรับ bokeh หลังจากเตรียมข้อมูลแล้ว เรามาดู setup ของพล็อตกันบ้าง ซึ่งเราจะเริ่มกันที่การเล่นสีนะครับโดยผมจะแบ่งสีเป็น 25 ขั้นจากแดงอ่อนไปแดงเข้มและมีความห่างขั้นละ 200(บาท) ถ้านับกำไรจาก 0 ก็จะไปสุดที่ 5000 บาทพอดีครับ โดยสีจะถูก map ให้ตรงกับเลขกำไรที่ทำขั้นบันไดเอาไว้ นอกจากนี้ feed ข้อมูลเข้าไปได้เลย แล้วก็ทำ tools bar ไว้ใช้ขยาย บันทึก รีเซ็ตกราฟ ฯลฯ
0 setup ต่างๆพร้อมแล้วก็ประกอบร่างกันเลย : วาง Layout, กำหนดช่องไฟ, แล้วก็ลงสีเข้าไปในช่องได้เลย หากใครงงโค้ดไม่ต้องตกใจนะครับ ลองตามๆไปก่อน เพราะโค้ดส่วนนี้ผมเองก็ลอกจากตัวอย่างมาตรงๆเหมือนกันครับ
1 กราฟมาแล้ว! เรียกว่ามาถูกทางเลยครับ แต่ยังต้องเพิ่มเติม Color bar เอาไว้ใช้เป็น reference ในการอ่านข้อมูล นอกจากนี้ยังขาดการจัดเรียงข้อมูล interactive ให้สวยๆ ว่าแล้วก็ไปลุยกันต่อเลยจ้า
2 พล็อตกราฟย้อนหลัง 6 เดือนมันก็จะดูคูลๆหน่อยครับ สิบปากว่าไม่เท่าตาเห็นจริงๆ Data Visualization ช่วยให้เราเห็นภาพอย่างแท้จริง รู้เลยว่าสินค้าตัวไหนให้กำไรเยอะ ตัวไหนเป็นสินค้ามาใหม่ ตัวไหนสร้างยอดต่อเนื่อง ทำให้พ่อค้าบ้านๆอย่างเรานำข้อมูลไปวางแผนงานต่างๆได้ตรงประเด็นมากขึ้นเยอะครับ สรุปทั้ง 2 Partและแล้วก็มาถึงจุดสิ้นสุดของ Tutorial นี้นะครับ เราลองมาทบทวนอีกครั้งว่าเราได้อะไรกันไปบ้าง ใน Part 1 เราได้ใช้ Python ในการเตรียมรายงานภาพรวมธุรกิจให้เรา เริ่มจากการการนำข้อมูลที่มีมาทำการปรับปรุงให้พร้อมใช้งาน(Read -> Clean -> Join) และ Export รายงานออกมา ซึ่งเราสามารถใช้ Script เดิมรันข้อมูลใหม่ๆได้ทุกวัน เหมาะกับรายงานที่ต้องทำเป็นประจำ ส่วนใน Part 2 เราได้ใช้ Python ในการเขียน Function ในการคัดกรองรายละเอียดสินค้าแบบเจาะลึก และได้ทำ Data Visualization อย่างง่ายกัน อย่างไรก็ตามสิ่งที่สำคัญไม่น้อยกว่าการวิเคราะห์ข้อมูลก็คือการเก็บข้อมูลนะครับ เราควรปรับวิธีการบันทีกข้อมูลเป็นประจำและหมั่นตรวจสอบรอยรั่วของการเก็บข้อมูลเหล่านั้น สำหรับ Tutorial นี้ หากมีผิดพลาดผมต้องขออภัยอีกครั้งนะครับและขอขอบคุณผู้อ่านทุกท่านที่สละเวลามาอ่าน blog นี้ ไว้เจอกันใหม่ blog ถัดไปนะครับ สวัสดี สุดท้ายนี้ ผมขอขอบคุณจารย์ตุลย์ @bluenex และ จารย์มาย @titipata ที่ช่วยพิสูจน์อักษรทั้ง 2 Part ขอขอบคุณ 425degreeที่ช่วยสนับสนุนข้อมูลเบื้องต้นให้นะครับ |