numpy เป็นมอดูลที่ทำให้เราสามารถใช้ออบเจ็กต์ชนิดที่เรียกว่า ndarray ซึ่งหมายถึงอาเรย์หลายมิติ บางครั้งก็เรียกว่าอาเรย์เฉยๆ
  คำว่า "อาเรย์" นั้นเป็นคำที่ถูกใช้ในภาษาอื่นๆอีกหลายภาษา เช่น ภาษาซี, php, จาวาสคริปต์, รูบี เป็นต้น แต่ว่าสำหรับในภาษาไพธอนสิ่งที่มีคุณสมบัติเทียบเท่ากับอาเรย์ในภาษาอื่น นั้นกลับเรียกว่าลิสต์ ส่วนอาเรย์จะหมายถึง ndarray ของ numpy 
 ในมอดูลมาตรฐานของภาษาไพธอนก็มีสิ่งที่เรียกว่าอาเรย์อยู่ แต่ก็ไม่เป็นที่นิยมใช้ ดังนั้นพอพูดถึงอาเรย์ในภาษาไพธอนแล้วจึงมักหมายถึง ndarray ของ numpy นั่นเอง 
 ก่อนที่จะเริ่มใช้งานสิ่งที่ต้องทำเป็นอย่างแรกก็คือทำการ import เรียกใช้ขึ้นมาก่อน
import numpy as np
 ตัวย่อ np นี้จะใช้แบบนี้ไปตลอดในบทความทุกบท เพราะค่อนข้างเป็นสากล แม้แต่เวลาที่เรียกชื่อฟังก์ชันต่างๆใน numpy ก็จะเรียกโดยขึ้นต้นด้วย np.    
การสร้างอาเรย์ขึ้นจากลิสต์ มีอยู่หลายวิธีในการสร้างอาเรย์ แต่วิธีที่พื้นฐานที่สุดคือสร้างขึ้นมาจากลิสต์, ทูเพิล หรือเรนจ์ โดยใช้ np.array(ลิสต์)
aray = np.array(range(3,7))
 araya = np.array([[1,2],[3,4]])
 print(aray)
 print(araya)
 ได้
[3 4 5 6]
 [[1 2]
  [3 4]]
 เท่านี้ก็จะได้อาเรย์ขึ้นมาตามที่ต้องการ ถ้าดูเผินๆจะเห็นว่าไม่ต่างอะไรจากลิสต์นัก แต่ความจริงแล้วต่างไปพอสมควร 
 ที่อาจจะเห็นได้เป็นอย่างแรกก็คือเวลาที่สั่ง print จะออกมาเป็นแถวเป็นระเบียบร้อยอย่างที่เห็นโดยอัตโนมัติ ทำให้ดูเข้าใจง่ายขึ้นมาก 
 อย่างต่อมาคืออาเรย์มีแอตทริบิวต์ติดตัวที่สามารถให้ข้อมูลของตัวอาเรย์นั้น เช่น 
| shape | รูปร่างของอาเรย์ | 
| size | จำนวนสมาชิกในอาเรย์ | 
| ndim | จำนวนมิติของอาเรย์ | 
 ลองเอาอาเรย์ ๒ ตัวจากตัวอย่างเมื่อครู่มาหาแอตทริบิวต์
print(aray.shape) # ได้ (4,)
 print(aray.size) # ได้ 4
 print(aray.ndim) # ได้ 1
 print(araya.shape) # ได้ (2, 2)
 print(araya.size) # ได้ 4
 print(araya.ndim) # ได้ 2
 นอกจากนี้ยังสามารถใช้ฟังก์ชันที่ชื่อเหมือนกับแอตทริบิวต์เหล่านี้ในการหาค่าได้ด้วย ผลที่ได้จะเหมือนกัน
print(np.size(araya))
 print(np.shape(araya))
 print(np.ndim(araya))
 จะเห็นว่ากรณีที่ลิสต์ที่ใช้นั้นมีการซ้อนกันก็จะได้เป็นอาเรย์ ๒ มิติ โดยมีแนวตั้งเป็นมิติที่หนึ่ง แนวนอนเป็นมิติที่สอง 
 และยังสามารถซ้อนกันเป็นมิติที่สูงขึ้นไปอีกได้ เช่นลองสร้าง ๓ มิติ
araye = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
 print(araye)
 print(araye.shape)
 print(araye.size)
 print(araye.ndim)
 ได้
[[[1 2]
   [3 4]]
 
  [[5 6]
   [7 8]]]
 (2, 2, 2)
 8
 3
 โดยมิติที่สามนั้นหากนำมาวาดเป็นรูปแล้วละก็อาจแสดงได้ในรูปของแถวในแนวลึกที่เพิ่มเข้ามา  
 
  สำหรับ สี่มิติขึ้นไปจะเริ่มอยู่เหนือสามัญสำนึกของคนทั่วไป งานที่จะต้องใช้มิติมากขนาดนั้นก็มักจะค่อนข้างเฉพาะทาง ดังนั้นจะไม่ขอกล่าวถึง 
 เนื้อหาส่วนใหญ่ในบทต้นๆจะเน้นหนึ่งถึงสองมิติเป็นหลัก และสำหรับสามมิติจะเริ่มเน้นใน
บทที่ ๒๓    มีข้อควรระวังคือลิสต์ที่จะใช้สร้างอาเรย์จะต้องมีจำนวนสมาชิกในลิสต์ย่อยแต่ละลิสต์เท่ากันไม่เช่นนั้นจะถูกตีความเป็นออบเจ็กต์ทั่วไป
arayu = np.array([[1,2],[3,4,5]])
 print(arayu.shape) # ได้ (2,)
 print(arayu.size) # ได้ 2
 print(arayu.ndim) # ได้ 1
 จะเห็นว่าผลที่ได้คือมันกลายเป็นอาเรย์มิติเดียวซึ่งมีขนาดเป็น 2 นั่นเพราะ [1,2] และ [3,4,5] ถูกตีความเป็นออบเจ็กต์อย่างละชิ้น แทนทีจะคิดเป็นตัวๆแยกกัน    
ชนิดของข้อมูลในอาเรย์ สามารถตรวจสอบชนิดของข้อมูลในอาเรย์ได้โดยดูที่แอตทริบิวต์ชื่อ dtype 
 เช่นลองใช้อาเรย์ที่สร้างในตัวอย่างก่อน
araye = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
 arayu = np.array([[1,2],[3,4,5]])
 print(araye.dtype) # ได้ int64
 print(arayu.dtype) # ได้ object
 จะเห็นว่า arayu ซึ่งสร้างขึ้นมาจากลิสต์ที่มีจำนวนสมาชิกไม่เท่ากันนั้นได้ข้อมูลประเภท object แทนที่จะเป็น int อย่างที่ควรเป็น 
 ส่วน araye นั้นกลายเป็นชนิด int ตามที่ควรจะเป็น โดยเลข 64 ใน int64 นี้บอกถึงขนาดของหน่วยความจำเป็นบิตที่ใช้ในการเก็บตัวเลข ปกติแล้วในภาษาไพธอนจำนวนเต็มจะไม่ได้แบ่งชนิดย่อย แต่ในบางภาษาเช่นภาษาซีจำนวนเต็มจะถูกแบ่งเป็นชนิดตามขนาดของหน่วยความจำที่ ใช้ 
 ปกติแล้วถ้าไม่ได้ระบุอะไรข้อมูลจำนวนเต็มจะถูกตั้งให้เป็น int64 ซึ่งเป็นขนาดใหญ่สุด นอกจาก int64 แล้วก็ยังมี int8 int16 int32 ซึ่งจะกินพื้นที่น้อยกว่า และ float เองก็มีแบ่งเช่นกัน 
 ชนิดของข้อมูลสามารถกำหนดได้ตอนที่สร้างอาเรย์ขึ้นมา โดยเพิ่มคีย์เวิร์ด dtype เข้าไป
ari = np.array([1,2,3,4],dtype='int16')
 ariy = np.array([1,2,3,4],dtype='float32')
 print(ariy) # ได้ [ 1.  2.  3.  4.]
 ถ้าตอนสร้างมีสมาชิกที่มีทศนิยมแม้แต่ตัวเดียวทั้งหมดก็จะกลายเป็น float64 ทันที
arey = np.array([1,2,3.14,4])
 print(arey) # ได้ [ 1.    2.    3.14  4.  ]
 print(arey.dtype) # ได้ float64
 จะเห็นว่าข้อมูลในอาเรย์จะต้องประกอบจากตัวแปรชนิดเดียวกันหมดทุกตัว หากตอนที่สร้างอาเรย์ขึ้นจากลิสต์นั้นมีสมาชิกที่ชนิดต่างกันจะถูกทำให้เหมือนกันหมด 
 กรณีที่มีสายอักขระปนอยู่ตัวอื่นก็จะถูกเปลี่ยนเป็นสายอักขระไปด้วย เช่น
arayo = np.array([[1,2],[3.,'4']])
 print(arayo)
 print(arayo.dtype)
 ได้
[['1' '2']
  ['3.0' '4']]
  <U32
  U ในที่นี้หมายถึงเป็นยูนิโค้ด และ 32 เป็นจำนวนหน่วยความจำที่ใช้ โดยปกติจะเท่ากับจำนวนตัวอักษรแต่ถ้าสั้นกว่า 32 จะถูกกำหนดให้เป็น 32 
 ใน ภาษาซีเวลาที่ประกาศตัวแปรชนิดสายอักขระจะต้องกำหนดความยาวไว้ตายตัว ดังนั้นอาเรย์ซึ่งตั้งอยู่บนพื้นฐานของภาษาซีจึงมีลักษณะการจัดเก็บข้อมูลใน ลักษณะนี้ไปด้วย 
 อนึ่ง 
 ความยาวของสายอักขระสามารถกำหนดขึ้นเองได้ และถ้ากำหนดความยาวต่ำกว่าจำนวนตัวอักษรก็จะถูกตัดทอนหายไป
print(np.array([[123456789]],dtype='<U5')) # ได้ [['12345']]
 นี่เป็นเนื้อหาที่เกี่ยวเนื่องมาจากภาษาซี จะไม่เน้นมาก ณ ที่นี้เพราะงานหลักของอาเรย์ที่จะใช้คือใช้กับตัวเลขเพื่อคำนวณ 
 อาเรย์สามารถเก็บข้อมูลชนิดสายอักขระได้ก็จริง แต่โดยทั่วไปมักจะใช้กับจำนวนตัวเลขมากกว่า เพื่อที่จะใช้ประโยชน์ในเรื่องการคำนวณอย่างเต็มที่ 
 ชนิดของอาเรย์ทั้งหมดสามารถดูได้ที่แอตทริบิวต์ np.sctypes
print(np.sctypes)
 ผลลัพธ์
{'int': [<class 'numpy.int8'>, <class 'numpy.int16'>, , <class 'numpy.int64'>], 'uint': [, <class 'numpy.uint16'>, , <class 'numpy.uint64'>], 'others': [, <class 'object'>, <class 'str'>, , <class 'numpy.void'>], 'float': [, <class 'numpy.float32'>, , <class 'numpy.float128'>], 'complex': [<class 'numpy.complex64'>, <class 'numpy.complex128'>, <class 'numpy.complex256'>]}
 ชนิดของสมาชิกในอาเรย์สามารถเปลี่ยนได้ด้วยเมธอด astype บนตัวอาเรย์
x = np.array([3.5,4.7,9,11.3,15])
 print(x) # ได้ [  3.5   4.7   9.   11.3  15. ]
 print(x.astype(int)) # ได้ [ 3  4  9 11 15]
 print(x.astype(str)) # ได้ ['3.5' '4.7' '9.0' '11.3' '15.0']
   การอ้างอิงถึงข้อมูลในอาเรย์ เช่น เดียวกับลิสต์ อาเรย์ก็ใช้การเติมวงเล็บเหลี่ยม [ ] เพื่ออ้างอิงข้อมูล โดยเลขในกรณีสองมิตินั้น ตัวแรกคือดัชนีของแนวตั้ง (เลขแถว) และตัวหลังคือแนวนอน (เลขหลัก)
ariyu = np.array([[1,2,3],[4,5,6]])
 print(ariyu[0][1]) # ได้ 2
 print(ariyu[1][2]) # ได้ 6
 แต่นอกจากนั้นแล้วยังสามารถเขียนโดยใช้เป็นคู่อันดับโดยมีจุลภาค , คั่นในวงเล็บเหลี่ยมตัวเดียวแทนการใส่วงเล็บเหลี่ยมสองอันได้ด้วย ซึ่งแบบนี้ลิสต์ไม่สามารถทำได้
print(ariyu[0,2]) # ได้ 3
 print(ariyu[1,1]) # ได้ 5
 การเข้าถึงสมาชิกทีละหลายตัวก็ทำได้ด้วยการใช้โคลอน : เช่นเดียวกับลิสต์ แต่สำหรันอาเรย์สองมิติแทนที่จะใช้วงเล็บเหลี่ยมวางต่อกันสองอันสามารถใช้จุลภาคแทนได้เช่นกัน
print(ariyu[1][:]) # ได้ [4 5 6]
 print(ariyu[1,:]) # ได้ [4 5 6]
  
  ซึ่งการที่ใช้จุลภาคแทนได้นั้นมีข้อดีคือเข้าถึงสมาชิกที่อยู่ในหลัก (แนวตั้ง) เดียวกันแต่คนละแถว (แนวนอน) โดยการใส่ : ไว้ทางซ้าย
print(ariyu[:,1]) # ได้ [2 5]
  
  ซึ่งจะเห็นได้ว่าการใช้วงเล็บเหลี่ยมคู่ [ ][ ] จะวาง [:] ไว้ซ้ายหรือขวาก็ให้ผลไม่ต่างจากเดิม คือให้สมาชิกที่อยู่ในแถวแนวนอนแถวเดียวกันเท่านั้น
print(ariyu[:][1]) # ได้ [4 5 6]]
 จะเห็นว่า [1,:] กับ [1][:] และ [:][1] ให้ผลเหมือนกัน แต่ [:,1] เท่านั้นที่จะให้ผลต่าง 
 ถ้าลองสร้างลิสต์แบบเดียวกันมาโดยไม่แปลงเป็นอาเรย์จะพบว่าไม่สามารถทำในสิ่งเดียวกันได้
liyu = [[1,2,3],[4,5,6]]
 print(liyu[:][1]) # ได้ [4 5 6]
 print(liyu[:,1]) # ได้ TypeError: list indices must be integers or slices, not tuple
 สรุปเป็นตารางเพื่อให้เห็นภาพชัด สมมุติว่าอาเรย์มี n แถว m หลัก
| แถว/หลัก | 0 | 1 | 2 | 3 | .. | m-1 | 
| 0 | [0,0] | [0,1] | [0,2] | [0,3] | [0,..] | [0,m-1] | 
| 1 | [1,0] | [1,1] | [1,2] | [1,3] | [1,..] | [1,m-1] | 
| 2 | [2,0] | [2,1] | [2,2] | [2,3] | [2,..] | [2,m-1] | 
| 3 | [3,0] | [3,1] | [3,2] | [3,3] | [3,..] | [3,m-1] | 
| .. | [..,0] | [..,1] | [..,2] | [..,3] | [..,..] | [..,m-1] | 
| n-1 | [n-1,0] | [n-1,1] | [n-1,2] | [n-1,3] | [n-1,..] | [n-1,m-1] | 
 สำหรับสามมิติซึ่งมีขนาด 3,3,3 อาจเขียนได้ดังนี้  
 
   การวางตัวเลขไว้หน้าและหลัง : เพื่อคัดเลือกอาเรย์เฉพาะในช่วงที่ต้องการก็ทำได้เช่นเดียวกับลิสต์
ตัวอย่างกรณีหนึ่งมิติ