ฉันมีรหัสต่อไปนี้:
r = numpy.zeros(shape = (width, height, 9))
มันสร้างwidth x height x 9
เมทริกซ์ที่เต็มไปด้วยศูนย์ แต่ฉันต้องการทราบว่ามีฟังก์ชั่นหรือวิธีการเริ่มต้นพวกเขาแทนที่จะNaN
เป็นในวิธีที่ง่าย
ฉันมีรหัสต่อไปนี้:
r = numpy.zeros(shape = (width, height, 9))
มันสร้างwidth x height x 9
เมทริกซ์ที่เต็มไปด้วยศูนย์ แต่ฉันต้องการทราบว่ามีฟังก์ชั่นหรือวิธีการเริ่มต้นพวกเขาแทนที่จะNaN
เป็นในวิธีที่ง่าย
คำตอบ:
คุณไม่ค่อยต้องการลูปสำหรับการดำเนินการเวกเตอร์ในจำนวนมาก คุณสามารถสร้างอาร์เรย์ที่ไม่ได้กำหนดค่าเริ่มต้นและกำหนดให้กับรายการทั้งหมดได้ในครั้งเดียว:
>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.nan
>>> a
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
ฉันหมดเวลาทางเลือกa[:] = numpy.nan
ที่นี่และa.fill(numpy.nan)
โพสต์โดย Blaenk:
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)"
10000 loops, best of 3: 54.3 usec per loop
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a[:] = np.nan"
10000 loops, best of 3: 88.8 usec per loop
การกำหนดเวลาแสดงการตั้งค่าสำหรับndarray.fill(..)
เป็นทางเลือกที่เร็วขึ้น OTOH ฉันชอบความสะดวกของผู้ใช้งานที่คุณสามารถกำหนดค่าให้กับส่วนทั้งหมดในเวลานั้นความตั้งใจของรหัสนั้นชัดเจนมาก
โปรดทราบว่าการndarray.fill
ดำเนินการดำเนินงานในสถานที่เพื่อจะกลับมาแทนnumpy.empty((3,3,)).fill(numpy.nan)
None
a = numpy.empty((3, 3,)) * numpy.nan
ฉันเช่นนี้: มันจับเวลาเร็วกว่าfill
แต่ช้ากว่าวิธีการมอบหมาย แต่มันเป็นแบบออนไลน์ !!
.fill()
วิธีนี้มากกว่า แต่ความแตกต่างของความเร็วจะลดลงจนแทบไม่มีอะไรเลยเมื่ออาร์เรย์มีขนาดใหญ่ขึ้น
np.empty([2, 5])
สร้างอาเรย์แล้วfill()
แก้ไขอาเรย์นั้นแทน แต่จะไม่ส่งคืนสำเนาหรือการอ้างอิง หากคุณต้องการโทรnp.empty(2, 5)
ด้วยชื่อ ("มอบหมายให้กับตัวแปร") คุณต้องทำก่อนที่จะทำการดำเนินการในที่ [1, 2, 3].insert(1, 4)
เดียวกันสิ่งที่เกิดขึ้นครับถ้าคุณทำ รายการถูกสร้างขึ้นและแทรก 4 แต่มันเป็นไปไม่ได้ที่จะได้รับการอ้างอิงไปยังรายการ (และมันสามารถสันนิษฐานได้ว่ามีการเก็บขยะ) บนข้อมูลที่ไม่เปลี่ยนรูปเช่นสตริงข้อความจะถูกส่งคืนเนื่องจากคุณไม่สามารถใช้งานได้ นุ่นสามารถทำทั้งสองอย่าง
อีกตัวเลือกหนึ่งคือการใช้numpy.full
ตัวเลือกที่มีอยู่ใน NumPy 1.8+
a = np.full([height, width, 9], np.nan)
มันมีความยืดหยุ่นและคุณสามารถใส่หมายเลขอื่น ๆ ที่คุณต้องการได้
full
มีไว้สำหรับ np.empy((x,y))*np.nan
เป็นนักวิ่งที่ดี (และใช้งานร่วมกันได้สำหรับเวอร์ชันเก่าของ numpy)
fill
python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)" 100000 loops, best of 3: 13.3 usec per loop python -mtimeit "import numpy as np; a = np.full((100,100), np.nan);" 100000 loops, best of 3: 18.5 usec per loop
python -mtimeit "import numpy as np; a = np.empty((1000,1000)); a.fill(np.nan)" 1000 loops, best of 3: 381 usec per loop $ python -mtimeit "import numpy as np; a = np.full((1000,1000), np.nan);" 1000 loops, best of 3: 383 usec per loop
ฉันเปรียบเทียบทางเลือกที่แนะนำสำหรับความเร็วและพบว่าสำหรับเวกเตอร์ / เมทริกซ์ที่มีขนาดใหญ่พอที่จะเติมเต็มทางเลือกทั้งหมดยกเว้นval * ones
และarray(n * [val])
เร็วพอ ๆ กัน
รหัสในการทำซ้ำพล็อต:
import numpy
import perfplot
val = 42.0
def fill(n):
a = numpy.empty(n)
a.fill(val)
return a
def colon(n):
a = numpy.empty(n)
a[:] = val
return a
def full(n):
return numpy.full(n, val)
def ones_times(n):
return val * numpy.ones(n)
def list(n):
return numpy.array(n * [val])
perfplot.show(
setup=lambda n: n,
kernels=[fill, colon, full, ones_times, list],
n_range=[2 ** k for k in range(20)],
logx=True,
logy=True,
xlabel="len(a)",
)
numpy.full(n, val)
ช้ากว่าa = numpy.empty(n) .. a.fill(val)
เพราะมันทำสิ่งเดียวกันภายใน
คุณคุ้นเคยnumpy.nan
หรือไม่
คุณสามารถสร้างวิธีการของคุณเองเช่น:
def nans(shape, dtype=float):
a = numpy.empty(shape, dtype)
a.fill(numpy.nan)
return a
แล้วก็
nans([3,4])
จะส่งออก
array([[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN]])
คุณสามารถใช้การคูณได้เสมอถ้าคุณจำไม่ได้ทันที.empty
หรือ.full
วิธีการ:
>>> np.nan * np.ones(shape=(3,2))
array([[ nan, nan],
[ nan, nan],
[ nan, nan]])
แน่นอนมันทำงานได้กับค่าตัวเลขอื่น ๆ เช่นกัน:
>>> 42 * np.ones(shape=(3,2))
array([[ 42, 42],
[ 42, 42],
[ 42, 42]])
แต่คำตอบที่ได้รับการยอมรับของ @ u0b34a0f6ae นั้นเร็วกว่า 3 เท่า (รอบการทำงานของ CPU ไม่ใช่รอบการทำงานของสมองที่จะจดจำไวยากรณ์ที่มีอยู่):
$ python -mtimeit "import numpy as np; X = np.empty((100,100));" "X[:] = np.nan;"
100000 loops, best of 3: 8.9 usec per loop
(predict)laneh@predict:~/src/predict/predict/webapp$ master
$ python -mtimeit "import numpy as np; X = np.ones((100,100));" "X *= np.nan;"
10000 loops, best of 3: 24.9 usec per loop
อีกทางเลือกหนึ่งคือnumpy.broadcast_to(val,n)
ผลตอบแทนในเวลาคงที่โดยไม่คำนึงถึงขนาดและยังเป็นหน่วยความจำที่มีประสิทธิภาพมากที่สุด (มันจะคืนค่ามุมมองขององค์ประกอบที่ทำซ้ำ) ข้อแม้คือค่าที่ส่งคืนเป็นแบบอ่านอย่างเดียว
ด้านล่างนี้คือการเปรียบเทียบของการแสดงของทุกวิธีการอื่น ๆ ที่ได้รับการเสนอให้ใช้มาตรฐานเช่นเดียวกับในคำตอบของนิโก้Schlömer
อย่างที่กล่าวไว้ว่า numpy.empty () เป็นวิธีที่จะไป อย่างไรก็ตามสำหรับวัตถุให้เติม () อาจไม่ทำสิ่งที่คุณคิดว่า:
In[36]: a = numpy.empty(5,dtype=object)
In[37]: a.fill([])
In[38]: a
Out[38]: array([[], [], [], [], []], dtype=object)
In[39]: a[0].append(4)
In[40]: a
Out[40]: array([[4], [4], [4], [4], [4]], dtype=object)
วิธีการหนึ่งสามารถเป็นเช่น:
In[41]: a = numpy.empty(5,dtype=object)
In[42]: a[:]= [ [] for x in range(5)]
In[43]: a[0].append(4)
In[44]: a
Out[44]: array([[4], [], [], [], []], dtype=object)
ความเป็นไปได้อื่นที่ยังไม่ได้กล่าวถึงที่นี่คือการใช้แผ่นกระเบื้อง NumPy:
a = numpy.tile(numpy.nan, (3, 3))
ยังให้
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
ฉันไม่รู้เกี่ยวกับการเปรียบเทียบความเร็ว
np.nan
จะผิดพลาดเมื่อเปลี่ยนเป็น int