φυβλαςのβλογ
บล็อกของ phyblas



numpy & matplotlib เบื้องต้น บทที่ ๑๙: ดัชนีบูลและดัชนีแฟนซี กับการคัดกรองส่วนประกอบในอาเรย์
เขียนเมื่อ 2016/06/11 23:53
แก้ไขล่าสุด 2022/07/21 20:30
ในบทที่ ๒​ ได้พูดถึงการเข้าถึงสมาชิกในอาเรย์ในเบื้องต้นไปแล้ว แต่นั่นเป็นแค่เบื้องต้น มีวิธีการเข้าถึงอาเรย์ที่ยืดหยุ่นกว่านั้นแม้ว่าอาจจะเข้าใจยากสักหน่อย นั่นคือการอ้างอิงเข้าถึงส่วนประกอบบางส่วนภายในอาเรย์โดยใช้อาเรย์อีกอันมาทำหน้าที่เป็นดัชนี

อาเรย์ที่ใช้เป็นดัชนีได้นั้นต้องเป็นอาเรย์ของจำนวนเต็ม หรือไม่ก็อาเรย์ของข้อมูลชนิดบูล (True และ False)

กรณีที่ใช้อาเรย์เป็นข้อมูลชนิดบูลจะเป็นการเข้าถึงสมาชิกภายในอาเรย์เฉพาะที่ค่าในอาเรย์ของดัชนีนั้นเป็น True

กรณีที่ใช้อาเรย์เป็นจำนวนเต็ม จำนวนเต็มนั้นจะแทนเลขดัชนีของข้อมูลที่ต้องการ ซึ่งเมื่อประกอบด้วยหลายตัวก็ทำให้เราเข้าถึงสมาชิกในตำแหน่งที่ต้องการทีละหลายตัวตามที่ระบุได้ การใช้ดัชนีในลักษณะนี้บางครั้งถูกเรียกว่าดัชนีแฟนซี (fancy index)

ทั้งดัชนีบูลและดัชนีแฟนซีเป็นเครื่องมือที่สะดวกมากในการคัดกรองส่วนประกอบภายในอาเรย์ออกมาบางส่วนตามที่เราต้องการโดยการกำหนดเงื่อนไขบางอย่าง

นอกจากนี้ในนี้จะพูดถึงฟังก์ชันส่วนหนึ่งที่เกี่ยวข้อง ซึ่งก็ใช้ในการคัดกรองและจัดการกับสมาชิกในอาเรย์ ได้แก่ np.where, np.select และ np.choose



การใช้อาเรย์ของบูลเป็นดัชนีในอาเรย์
สมมุติมีอาเรย์หนึ่งมิติอยู่ตัวหนึ่ง
import numpy as np
z = np.array([0,1,2,3,4,5])

การเข้าถึงสมาชิกภายในอาเรย์ทีละหลายตัวนั้นก็ทำได้แบบเดียวกับลิสต์ แต่นอกจากนี้แล้วยังสามารถใช้อาเรย์ที่เก็บออบเจ็กต์ชนิดบูล
z[np.array([False, FalseTrue, False, True, False])] # ได้ [2 4]

การเขียนแบบนี้อาจดูยุ่งยากยืดยาวกว่าเดิม แต่ความจริงแล้วมีประโยชน์ในทางประยุกต์ใช้มาก นั่นเพราะปกติหากเราเอาอาเรย์มาใช้ในนิพจน์การเปรียบเทียบก็จะคืนค่าออกมา เป็นอาเรย์ของข้อมูลชนิดบูล
print(z>3) # ได้ [False False False False  True  True]
print(z%2==1) # ได้ [False  True False  True False  True]

ดังนั้นหากนำผลที่ได้จากนิพจน์นี้ไปใช้เป็นดัชนีในการเข้าถึงสมาชิกในอาเรย์ละก็ จะได้อาเรย์ที่มีสมาชิกเหลือแค่ตัวที่เข้าเงื่อนไข
print(z[z>3]) # ได้ [4 5]
print(z[z%2==1]) # ได้ [1 3 5]

ผลที่ได้ก็คือเป็นการคัดกรองสมาชิกภายในอาเรย์ให้เหลือเฉพาะบางส่วน การเขียนแบบนี้จึงมีประโยชน์มาก หากประยุกต์ให้ดีจะสามารถสร้างอาเรย์ในแบบที่ต้องการได้ง่ายมาก


ตัวอย่างการประยุกต์ใช้ เช่นลองคัดกรองข้อมูลบางส่วนที่เข้าเงื่อนไข แบ่งเอาไว้เป็นส่วนหนึ่ง ส่วนที่ไม่เข้าเงื่อนไขก็ไว้อีกส่วนหนึ่ง

เช่นลองแบ่งกราฟ sin ออกเป็น ๒ ส่วน ส่วนที่ค่าสูงกว่าและต่ำกว่า 0.4
import matplotlib.pyplot as plt
x = np.linspace(-15,15,10001)
y = np.cos(x)
plt.plot(x[y<0.4],y[y<0.4],'--',lw=2)
plt.plot(x[y>=0.4],y[y>=0.4],'r',lw=2)
plt.show()



หรืออาจใช้เงื่อนไขเป็นทั้งแกน x และ y ร่วมกัน เช่นคัดกรองจุดที่อยู่ภายในรัศมี 0.7 จากใจกลางออกไป
x = np.linspace(-1,1,4001)
y = np.cos(x*50)
plt.figure(figsize=[7,7])
plt.axes(aspect=1,xlim=[-1.1,1.1],ylim=[-1.1,1.1])
plt.scatter(x[x**2+y**2>0.7**2],y[x**2+y**2>0.7**2],s=30)
plt.show()



เราสามารถใช้วิธีนี้เข้าถึงสมาชิกบางส่วนเพื่อไปแก้ไขบางส่วน

เช่น แก้ข้อมูลที่ติดลบให้เป็น 0 ให้หมด
ay = np.random.randint(-9,9,10)
print(ay) # ได้ [ 8 -4  0  1 -5 -1  5 -2  1  1]
ay[ay<0] = 0
print(ay) # ได้ [8 0 0 1 0 0 5 0 1 1]

ลองดูตัวอย่างโดยวาดกราฟซึ่งมีการตัดข้อมูลส่วนที่ต่ำกว่า 0 ให้กลายเป็น 0 ทั้งหมด
x = np.linspace(0,2,2001)
y = np.cos(100*x)+np.sin(110*x)
y[y<0] = 0
plt.axes(ylim=[-2,2])
plt.plot(x,y)
plt.show()



หากใช้ตัวแปรมารับอาเรย์ที่ได้จากการเข้าถึงด้วยดัชนีบูล จะมีการคัดลอกค่าทั้งหมดเข้าไปเก็บในตัวแปรนั้น ไม่ได้เกิดการถ่ายทอด กล่าวคือหากมีการเปลี่ยนแปลงค่าภายในตัวแปรใหม่นั้นจะไม่กระทบถึงข้อมูลภายในอาเรย์เดิม
print(ay) # ได้ [-3 7 -5 -7 7 3 8 5 -8 -1]
ayw = ay[ay<0]
print(ayw) # ได้ [-3 -5 -7 -8 -1]
ayw[:] = 0
print(aw) # ได้ [0 0 0 0 0]
print(ay) # ได้ [-3 7 -5 -7 7 3 8 5 -8 -1]

ซึ่งจะเห็นว่าต่างจากการใช้ดัชนีเป็นเลขธรรมดาซึ่งมีคุณสมบัติการถ่ายทอด ดังนั้นต้องระวังอย่าสับสนกัน



ดัชนีในสองมิติ
กรณีที่ใช้ในสองมิติขึ้นไปจะมีความซับซ้อนขึ้นมาแต่หากเข้าใจแล้วก็จะประยุกต์ใช้ได้ดี

ก่อนอื่นทวนเนื้อหาจากบทที่แล้วสักหน่อย อาเรย์สองมิติประกอบไปด้วยแถว (แนวตั้ง) กับหลัก (แนวนอน)

ขอใช้อาเรย์นี้เป็นตัวอย่าง
z = np.array([[0,1,2,3],[10,11,12,13],[20,21,22,23]])
 


การเข้าถึงสมาชิกในอาเรย์สามารถใช้ลิสต์ของดัชนี โดยใช้เป็น [แถว,หลัก]
print(z[2,1]) # ได้ 21

ถ้าใส่แทนเลขหลักด้วย : หรือไม่ใส่เลย จะเป็นการเลือกเอาสมาชิกจากทุกหลักในแถวนั้น
print(z[2,:]) # ได้ [20 21 22 23]
print(z[2]) # ได้ [20 21 22 23]



แต่ถ้าใส่แทนเลขหลักด้วย : หรือไม่ใส่เลย และใส่แทนเลขแถวด้วยลิสต์ จะเป็นการเลือกเอาหลักที่มีดัชนีเป็นทุกตัวในลิสต์นั้น
print(z[[1,2],:])
# ได้
# [[10 11 12 13]
#  [20 21 22 23]]

print(z[[1,2]])
# ได้
# [[10 11 12 13]
#  [20 21 22 23]]

ถ้าใส่แทนเลขแถวด้วย : ใส่แทนหลักด้วยตัวเลขจะกลายเป็นการเลือกเอาสมาชิกจากทุกแถวในหลักนั้น
print(z[:,1]) # ได้ [ 1 11 21]



แต่ถ้าใส่แทนเลขแถวด้วย : แทนหลักด้วยลิสต์ ผลที่จะเป็นการเลือกเอาแถวที่มีดัชนีเป็นทุกตัวในลิสต์นั้นมาพร้อมกัน
print(z[:,[1,2]])
# ได้
# [[ 1  2]
#  [11 12]
#  [21 22]]



จากตรงนี้ เราลองเปลี่ยนมาลองใช้อาเรย์ชนิดบูลในการเข้าถึงสมาชิกในอาเรย์เช่นเดียวกับที่ทำในหนึ่งมิติ
  
ลองสร้างอาเรย์ที่เก็บค่าความจริงเท็จขึ้นมา จากนั้นลองนำไปใช้เป็นตัวระบุดัชนีในอาเรย์ z
fft = np.array([False,False,True])
print(fft) # ได้ [False False  True]
print(z[fft]) # ได้ [[20 21 22 23]]
print(z[fft,:]) # ได้ [[20 21 22 23]]



ซึ่งมีค่าเท่ากับ z[2] หรือ z[2,:]

จะเห็นว่าอาเรย์ fft ในที่นี้เป็นตัวระบุว่าจะเอาสมาชิกในแถวไหนของ z

ถ้าหากมี True อยู่ ๒ ตัว ก็จะได้ออกมา ๒ แถว
tft = np.array([True,False,True])
print(tft) # ได้ [ True False  True]
print(z[tft]) # หรือ print(z[tft,:]) ก็ได้
# ได้
# [[ 0  1  2  3]
#  [20 21 22 23]]



ซึ่งมีค่าเท่ากับ z[[1,2]] หรือ z[[1,2],:]

หากใช้วิธีเดียวกันแทนเลขหลักก็ได้ผลในลักษณะเดียวกัน
fftf = np.array([False,False,True,False])
print(fftf) # ได้ [False False  True False]
print(z[:,fftf])
# ได้
# [[ 2]
#  [12]
#  [22]]

tftf = np.array([True,False,True,False])
print(tftf) # ได้ [ True False  True False]
print(z[:,tftf])
# ได้
# [[ 0  2]
#  [10 12]
#  [20 22]]



ทีนี้อาเรย์มีคุณสมบัติการกระจาย ถ้าหากเอาอาเรย์มาเทียบกับค่าอะไรบางอย่างก็สามารถได้ผลออกมาเป็นอาเรย์ของค่าความจริงเท็จ
print(z==21)
# ได้
# [[False False False False]
#  [False False False False]
#  [False  True False False]]

จะเห็นว่าในนี้มีแค่สมาชิกตัวเดียวที่มีค่าเป็น 21 จึงคืนค่าเป็น True ที่เหลือเป็น False

ถ้าใช้วิธีนี้กับบางส่วนของอาเรย์ก็จะได้อาเรย์ของค่าความจริงเท็จที่มีมิติเดียว
print(z[2,:]==21) # ได้ [False  True False False]

ซึ่งเป็นสิ่งที่สามารถถูกนำมาใช้เป็นค่าดัชนีได้

ดังนั้นหากนำมาประยุกต์เราจะสามารถใช้เพื่อคัดกรองสมาชิกได้
print(z[:,z[2,:]==21]) # เอาอาเรย์หลักที่มีสมาชิกแถว 2 เป็น 21
# ได้
# [[ 1]
#  [11]
#  [21]]


print(z[z[:,2]==22,:]) # เอาอาเรย์แถวที่มีสมาชิกหลัก 2 เป็น 22
# ได้ [[20 21 22 23]]

print(z[z[:,2]>11,:]) # เอาอาเรย์แถวที่มีสมาชิกหลัก 2 มากกว่า 11
# ได้
# [[10 11 12 13]
#  [20 21 22 23]]

print(z[:,z[2,:]%10>1]) # เอาอาเรย์หลักที่มีสมาชิกแถว 2 หาร 10 แล้วเหลือเศษมากกว่า 1 (ก็คือมีเลขหลักหน่วยเป็น 2 ขึ้นไป)
# ได้
# [[ 2  3]
#  [12 13]
#  [22 23]]



หากนำทั้งอาเรย์มาเข้านิพจน์หาค่าความจริงเท็จก็จะได้อาเรย์ของ True False ที่มีขนาดตามนั้น เช่น
ay = np.random.randint(0,100,[4,4])
print(ay)
# ได้
# [[50 61  5 63]
#  [57 10 80 82]
#  [25 30 10 24]
#  [53 61 36 71]]

print(ay>50)
# ได้
# [[False  True False  True]
#  [ True False  True  True]
#  [False False False False]
#  [ True  True False  True]]

ซึ่งเมื่อเราเอาอาเรย์ที่ได้ตัวนี้มาเป็นดัชนีให้กับตัวอาเรย์นั้นเอง ผลที่ได้จะออกมาในรูปของอาเรย์หนึ่งมิติซึ่งประกอบด้วยสมาชิกเฉพาะส่วนที่เป็น True
print(ay[ay>50]) # ได้ [61 63 57 80 82 53 61 71]

ซึ่งจะเห็นว่าแบบนี้ทำให้สูญเสียมิติไป อย่างไรก็ตามแม้จะอยู่ในรูปหนึ่งมิติแต่อาเรย์ตัวนี้ก็ชี้ถึงสมาชิกแต่ละตัวในอาเรย์ตัวเดิมนี้อยู่ เราสามารถทำการแก้ข้อมูลมันได้
ay[ay>50] = 0
print(ay)
# ได้
# [[50  0  5  0]
#  [ 0 10  0  0]
#  [25 30 10 24]
#  [ 0  0 36  0]]

เท่านี้ตัวเลขที่มีค่ามากกว่า 50 ก็ถูกเปลี่ยนให้กลายเป็น 0 หมด



การใช้อาเรย์ของจำนวนเต็มเป็นดัชนี
อาเรย์ของข้อมูลชนิดจำนวนเต็ม รวมทั้งลิสต์ของจำนวนเต็ม สามารถใช้เพื่อเป็นดัชนีเพื่ออ้างอิงถึงสมาชิกในอาเรย์ได้ โดยจะเป็นการเข้าถึงสมาชิกทีละหลายตัวตามตัวเลขที่ระบุไว้นั้น

ตัวอย่าง
az = np.arange(0,100,10)
print(az) # [ 0 10 20 30 40 50 60 70 80 90]
print(az[[2,3,7]]) # [20 30 70]
ai = np.array([3,5,6]) # สร้างอาเรย์เพื่อใช้เป็นดัชนี
print(az[ai]) # ได้ [30 50 60]

การใช้ในลักษณะนี้มีประโยชน์มาก สามารถเอาไปประยุกต์ใช้เช่นเวลาที่มีข้อมูลที่ยาวมากๆแล้วต้องการจะยกแต่บางส่วนออกมาเป็นช่วงๆ

เช่น เวลาที่ต้องการวาดแค่บางจุดบนกราฟ
x = np.arange(10001)
y = np.sin(x/500.)
plt.plot(x,y) # กราฟเส้นของข้อมูลทั้งหมด
ai = np.arange(0,10001,200) # อาเรย์ที่ใช้เป็นดัชนี
plt.plot(x[ai],y[ai],'o') # กราฟจุดของข้อมูลที่กรองแล้ว
plt.show()



จะเห็นว่ามีข้อมูล 10001 ตัวที่ประกอบกันเป็นกราฟ sin แต่เราต้องการนำข้อมูลแค่บางส่วน โดยในที่นี้ให้วาดจุดแค่ทุก 200 ค่า กรณีแบบนี้ดัชนีแฟนซีจะมีประโยชน์มาก

กรณีที่มีการนำตัวแปรมารับค่าอาเรย์ที่ได้จากดัชนีแฟนซีก็จะได้ผลเช่นเดียวกับดัชนีบูลก็คือเป็นการคัดลอกอาเรย์ไปเก็บไว้ในตัวแปรใหม่ ไม่ใช่การถ่ายทอด หากมีการแก้ไขค่าอะไรในตัวแปรใหม่ก็จะไม่กระทบถึงอาเรย์ตัวเดิม



เรื่องของดัชนีแฟนซีนี้อาจจะเข้าใจยาก แต่หากใช้จนคล่องแล้วมันจะเป็นวิธีการในการคัดกรององค์ประกอบที่ทรงพลังมาก ยังไงก็คงจะพยายามเข้าใจมันสักหน่อย



np.where
เราสามารถใช้ฟังก์ชัน np.where เพื่อหาค่าดัชนีของสมาชิกภายในอาเรย์ที่เข้ากับเงื่อนไขบางอย่างที่ต้องการได้

np.where ต้องการอาร์กิวเมนต์เป็นนิพจน์ของอาเรย์ซึ่งให้ค่าความจริงเท็จ เช่น x>10 x==20 x!=3 เป็นต้น จากนั้นจะคืนค่าออกมาเป็นดัชนีของอาเรย์นั้นที่เข้าเงื่อนไข (ให้ผลค่าความจริงเป็นจริง)

ตัวอย่าง
a = np.linspace(10,13,6)
print(a) # ได้ [ 10.   10.6  11.2  11.8  12.4  13. ]
print(a>11) # ได้ [False False  True  True  True  True]
print(np.where(a>11)) # ได้ (array([2, 3, 4, 5]),)

จะเห็นว่า np.where(a>11) จะได้ผลออกมาเป็นอาเรย์ที่ประกอบไปด้วยเลขดัชนีของสมาชิกใน a ที่ให้ a>11 เป็น True

จากนั้นหากเอาผลที่ได้จาก np.where นี้มาใช้เป็นดัชนี
print(a[np.where(a>11)]) # ได้ [ 11.2  11.8  12.4  13. ]

จะเห็นว่าผลที่ได้จะเหมือนกับ a[a>11]
print(a[a>11]) # ได้ [ 11.2  11.8  12.4  13. ]

ซึ่งถ้าหากนำมาใช้ในลักษณะนี้ก็อาจดูไม่จำเป็น เพราะทำให้เขียนยาวขึ้นแต่ผลเหมือนเดิม

นอกจากนี้แล้ว np.where มีวิธีการใช้งานที่มากกว่านั้น ซึ่งทำได้โดยใส่อาร์กิวเมนต์เพิ่มเป็นสามตัว แบบนั้นจะเป็นการนำอาเรย์ตัวเดิมมาจัดการอะไรบางอย่างโดยขึ้นกับเงื่อนไขที่ ใส่ลงไป

การทำงานอาจเข้าใจยากเล็กน้อย ลองดูตัวอย่างเพื่อให้พอเห็นภาพ
a = np.linspace(10,13,6)
print(a) # ได้ [ 10.   10.6  11.2  11.8  12.4  13. ]
print(np.where(a>11,1,2)) # ได้ [2 2 1 1 1 1]

จะเห็นว่าการทำงานของ np.where ในที่นี้ก็คือจะพิจารณาค่าความจริงเท็จจากอาร์กิวเมนต์ตัวที่หนึ่ง ถ้าหากว่าเป็นจริงก็จะคืนค่าออกมาตามค่าที่ใส่ไว้ในอาร์กิวเมนต์ตัวที่สอง ถ้าเป็นเท็จก็จะคืนค่าตามอาร์กิวเมนต์ตัวที่สาม

ในที่นี้จะเห็นว่า สมาชิก ๒ ตัวแรกคือ 10.  กับ 10.6 ไม่เข้าเงื่อนไข (ให้ค่า False) จึงได้รับค่าที่อยู่ในอาร์กิวเมนต์ตัวที่สาม ก็คือ 2 ส่วนที่เหลือเป็น True จึงได้ค่า 1

ค่าที่ใส่นั้นอาจไม่ใช่แค่จำนวนค่าคงที่เท่านั้นแต่สามารถใส่ตัวอาเรย์ตัวนั้นเพื่อให้มันนำเอาสมาชิกในลำดับที่ตรงกันมาคำนวณ

เช่น
print(np.where(a>11,a+10,a-10)) # [  0.    0.6  21.2  21.8  22.4  23. ]

ในที่นี้สมาชิกใน a สองตัวแรกไม่เข้าเงื่อนไข a>11 จึงได้ค่าเป็น a-10 ค่าจึงลดลงไป 10 ส่วนตัวที่เหลือเข้าเงื่อนไขจึงบวกไป 10

อาเรย์ที่ใช้เป็นเงื่อนไขในอาร์กิวเมนต์ตัวแรกกับอาเรย์ที่ใช้พิจารณาค่าอาจไม่ใช่ตัวเดียวกันก็ได้ ขอแค่มีสมาชิกจำนวนเท่ากัน

ตัวอย่าง
b = np.linspace(20,24,6)
c = np.arange(1,7)
print(b) # ได้ [ 20.   20.8  21.6  22.4  23.2  24. ]
print(c) # ได้ [1 2 3 4 5 6]
print(c%2==0) # ได้ [False  True False  True False  True]
print(np.where(c%2==0,b,b/5)) # ได้ [  4.    20.8    4.32  22.4    4.64  24.  ]

ในตัวอย่างนี้ใช้ c เป็นเงื่อนไขโดยจะเห็นว่าตัวที่ 0,2,4 เป็น False ส่วน b ถูกใช้เป็นอาเรย์สำหรับนำค่ามาคำนวณ ค่าที่ได้จาก np.where ในที่นี้จะเป็นค่าของสมาชิกใน b ในตำแหน่งที่ได้ True ส่วนตำแหน่งที่ได้ False จะถูกหาร 5

และในบางครั้งอาจใช้เพื่อคัดเลือกว่าจะเอาค่าจากอาเรย์ตัวไหนตามเงื่อนไขที่กำหนดก็ได้
d = np.array([1100,1200,1300,1400])
e = np.array([11,12,13,14])
f = np.array([1,9,8,1])
print(np.where(f>1,e,d)) # ได้ [1100   12   13 1400]

เราอาจนำมาใช้เพื่อกรองค่าในฟังก์ชันบางส่วนที่ไม่ตรงเงื่อนไขที่ต้องการ ตัวอย่างเช่นลองสร้างกราฟของฟังก์ชัน sin โดยที่ให้ค่าที่ต่ำกว่า 0 เป็น 0 ไปให้หมด
x = np.arange(0,20,0.01)
y = np.sin(x)
y2 = np.where(y<0,0,y)
plt.subplot(211,ylim=[-1,1])
plt.plot(x,y)
plt.subplot(212,ylim=[-1,1])
plt.plot(x,y2)
plt.show()





np.select
มีอีกฟังก์ชันซึ่งคล้ายๆกับ np.where สามารถทำให้ได้ผลที่เหมือนกันได้ นั่นคือ np.select

ฟังก์ชันนี้จะทำการสร้างอาเรย์ใหม่ขึ้นมาจากอาเรย์เดิมที่ใช้เป็นตัวกำหนดเงื่อนไข ซึ่งจะใส่เป็นอาร์กิวเมนต์ตัวแรก ค่าในอาเรย์ที่สร้างขึ้นใหม่จะกำหนดโดยอาร์กิวเมนต์ตัวหลัง
x = np.array([1.1,1.3,1.6,1.7,2.1,2.4])
print(np.select([x>1.5,x<=1.5],[3,4])) # ได้ [4 4 3 3 3 3]

ในตัวอย่างนี้สมาชิกใน x สองตัวแรก 1.1,1.3 นั้นน้อยว่า 1.5 จึงเข้าเงื่อนไขหลังจึง

เงื่อนไขแรกกับเงื่อนไขหลังไม่จำเป็นต้องครอบคลุมทุกสิ่งที่เป็นไปได้ หากมีสมาชิกไหนที่ไม่เข้ากับเงื่อนไขเลยก็จะได้ค่า 0 เช่น
print(np.select([x>1.5,x<=1.2],[3,4])) # ได้ [4 0 3 3 3 3]

เงื่อนไขอาจมีกี่ตัวก็ได้ ซึ่งก็จะต้องเตรียมค่าที่จะใช้เมื่อเข้าเงื่อนไขนั้นให้มีจำนวนเท่ากันด้วย
print(np.select([x>1.8,x>1.5,x<=1.5],[2,3,4])) # ได้

ค่าในลิสต์ตัวหลังก็อาจใช้เป็นอาเรย์ตัวที่พิจารณาเองได้
print(np.select([x>1.8,x>1.5,x<=1.5],[2*x,0,4*x])) # ได้ [ 4.4  5.2  0.   0.   4.2  4.8]

และก็อาจใช้เป็นอาเรย์ตัวอื่นที่มีขนาดเท่ากัน
x = np.array([1.1,1.3,1.6,1.7,2.1,2.4])
a = np.array([100,200,300,400,500,600])
b = np.array([10,20,30,40,50,60])
c = np.array([1,2,3,4,5,6])
print(np.select([x>1.8,x>1.5,x<=1.5],[a*x,b*x,c*x])) # ได้ [ 1100.  2600.   480.   680.   105.   144.]

เราอาจประยุกต์ใช้เพื่อทำกราฟที่มีค่าแบ่งเป็นช่วงๆก็ได้
x = np.linspace(-2,4,600)
y = x**2
y2 = np.select([x<-1,x<=3,x>3],[1,y,9])
plt.figure(figsize=[6,8])
plt.subplot(211,ylim=[-1,10],title='$y=x^2$')
plt.plot(x,y)
plt.subplot(212,ylim=[-1,10],title=r'$y=1|x\leq-1,x^2|x\in(-1,3],9|x>3$')
plt.plot(x,y2)
plt.subplots_adjust(0.05,0.05,0.96,0.95,0.4,0.4)
plt.show()





np.choose
ฟังก์ชัน np.choose มีไว้สร้างอาเรย์ขึ้นจากรายการ (ลิสต์หรืออาเรย์) ของเลขดัชนี และรายการของค่าที่ต้องการนำมาใช้

เพื่อให้เข้าใจจำเป็นต้องดูตัวอย่างการใช้
s = np.array([1,1,1,2,2,0,1,3]) # อาเรย์เก็บดัชนีตัวเลือก
g = np.array([0.1,3.1,5.1,6.1]) # อาเรย์เก็บค่าที่จะใช้
print(np.choose(s,g)) # ได้ [ 3.1  3.1  3.1  5.1  5.1  0.1  3.1  6.1]

จากตัวอย่างนี้จะเป็นการสร้างอาเรย์ที่ใช้อาร์กิวเมนต์ตัวแรกเป็นเลขดัชนีและ ตัวหลังเป็นค่าที่จะให้นำมาใช้เมื่อถูกอ้างอิงจากดัชนี ผลลัพธ์ที่ได้จะมีจำนวนสมาชิกเท่ากับอาเรย์ที่เก็บดัชนีตัวเลือก

จริงๆแล้วเราสามารถได้ผลแบบเดียวกันนี้ด้วยการเขียนง่ายๆเป็น g[s]
print(g[s]) # ได้ [ 3.1  3.1  3.1  5.1  5.1  0.1  3.1  6.1]

ซึ่งก็เป็นไปตามหลักของดัชนีแฟนซี



อ้างอิง


<< บทที่แล้ว     บทถัดไป >>
หน้าสารบัญ


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> numpy

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文