我有以下代码:
r = numpy.zeros(shape = (width, height, 9))
Run Code Online (Sandbox Code Playgroud)
它创建一个用零填充的宽x高x 9矩阵.相反,我想知道是否有一种功能或方法来初始化它们而不是NaN.
有没有?无需诉诸手动循环等?
谢谢
u0b*_*6ae 233
你很少需要在numpy中进行向量操作的循环.您可以创建一个未初始化的数组并立即分配给所有条目:
>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.nan
>>> a
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
Run Code Online (Sandbox Code Playgroud)
我在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
Run Code Online (Sandbox Code Playgroud)
时间表明偏好ndarray.fill(..)作为更快的选择.OTOH,我喜欢numpy的便利实现,你可以在那里为整个切片分配值,代码的意图非常明确.
小智 136
另一种选择是使用numpy.fullNumPy 1.8+中提供的选项
a = np.full([height, width, 9], np.nan)
Run Code Online (Sandbox Code Playgroud)
这非常灵活,您可以使用您想要的任何其他数字填充它.
Nic*_*mer 36
我比较了建议的速度替代方案,并发现,对于足够大的矢量/矩阵来填充,所有替代方案除外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)'
)
Run Code Online (Sandbox Code Playgroud)
Jor*_*eña 25
你熟悉numpy.nan吗?
您可以创建自己的方法,例如:
def nans(shape, dtype=float):
a = numpy.empty(shape, dtype)
a.fill(numpy.nan)
return a
Run Code Online (Sandbox Code Playgroud)
然后
nans([3,4])
Run Code Online (Sandbox Code Playgroud)
会输出
array([[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN]])
Run Code Online (Sandbox Code Playgroud)
我在邮件列表线程中找到了这段代码.
hob*_*obs 10
如果您不立即回想起.empty或.full方法,您可以随时使用乘法:
>>> np.nan * np.ones(shape=(3,2))
array([[ nan, nan],
[ nan, nan],
[ nan, nan]])
Run Code Online (Sandbox Code Playgroud)
当然它也适用于任何其他数值:
>>> 42 * np.ones(shape=(3,2))
array([[ 42, 42],
[ 42, 42],
[ 42, 42]])
Run Code Online (Sandbox Code Playgroud)
但是@ u0b34a0f6ae 接受的答案要快3倍(CPU周期,而不是脑循环来记住numpy语法;):
$ 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
Run Code Online (Sandbox Code Playgroud)
这里尚未提及的另一种可能性是使用 NumPy 瓦片:
a = numpy.tile(numpy.nan, (3, 3))
Run Code Online (Sandbox Code Playgroud)
还给出
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
Run Code Online (Sandbox Code Playgroud)
更新:我做了速度比较,它不是很快:/它比ones_times小数点慢。
如前所述, numpy.empty() 是要走的路。但是,对于对象,fill() 可能不会完全按照您的想法执行:
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)
Run Code Online (Sandbox Code Playgroud)
一种解决方法可以是例如:
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)
Run Code Online (Sandbox Code Playgroud)
另一种选择是numpy.broadcast_to(val,n)无论大小如何都以恒定时间返回并且也是最有效的内存(它返回重复元素的视图)。需要注意的是,返回的值是只读的。
以下是使用与Nico Schlömer 的答案相同的基准提出的所有其他方法的性能比较。
| 归档时间: |
|
| 查看次数: |
182167 次 |
| 最近记录: |