创建一个包含随机NaN值的示例numpy数组。

13

为了测试目的,我想要创建一个 M by N 的 numpy 数组,其中有 c 个随机放置的 NaN。

import numpy as np

M = 10;
N = 5;
c = 15;
A = np.random.randn(M,N)

A[mask] = np.nan

我在创建一个具有 c 个真元素的掩码时遇到了问题,或者也许可以直接用索引实现?

2个回答

19
你可以使用可选的replace=False参数来进行非重复的随机选择,然后将其应用于A的扁平化版本(使用.ravel()完成),方法如下所示:np.random.choice
A.ravel()[np.random.choice(A.size, c, replace=False)] = np.nan

示例运行 -

In [100]: A
Out[100]: 
array([[-0.35365726,  0.26754527, -0.44985524, -1.29520237,  2.01505444],
       [ 0.01319146,  0.65150356, -2.32054478,  0.40924753,  0.24761671],
       [ 0.3014714 , -0.80688589, -2.61431163,  0.07787956,  1.23381951],
       [-1.70725777,  0.07856845, -1.04354202, -0.68904925,  1.07161002],
       [-1.08061614,  1.17728247, -1.5913516 , -1.87601976,  1.14655867],
       [ 1.12542853, -0.26290025, -1.0371326 ,  0.53019033, -1.20766258],
       [ 1.00692277,  0.171661  , -0.89646634,  1.87619114, -1.04900026],
       [ 0.22238353, -0.6523747 , -0.38951426,  0.78449948, -1.14698869],
       [ 0.58023183,  1.99987331, -0.85938155,  1.4211672 , -0.43369898],
       [-2.15682219, -0.6872121 , -1.28073816, -0.97523148, -2.27967001]])

In [101]: A.ravel()[np.random.choice(A.size, c, replace=False)] = np.nan

In [102]: A
Out[102]: 
array([[        nan,  0.26754527, -0.44985524,         nan,  2.01505444],
       [ 0.01319146,  0.65150356, -2.32054478,         nan,  0.24761671],
       [        nan, -0.80688589,         nan,         nan,  1.23381951],
       [        nan,         nan, -1.04354202, -0.68904925,  1.07161002],
       [-1.08061614,  1.17728247, -1.5913516 ,         nan,  1.14655867],
       [ 1.12542853,         nan, -1.0371326 ,  0.53019033, -1.20766258],
       [        nan,  0.171661  , -0.89646634,         nan,         nan],
       [ 0.22238353, -0.6523747 , -0.38951426,  0.78449948, -1.14698869],
       [ 0.58023183,  1.99987331, -0.85938155,         nan, -0.43369898],
       [-2.15682219, -0.6872121 , -1.28073816, -0.97523148,         nan]])

哦,那比我的方法更优雅! - tmdavison
我想我也可以用np.random.randint(0,high=A.size,size=c)替换我的应用中的np.random.choice(如果替换不会真正影响)。但是,ravel()之后为什么数组没有保持平坦? - Oleg
@OlegKomarov np.random.randint 可能会给你重复的索引,所以我不认为在你的情况下会起作用。关于 .ravel() 的事情,它只是一个 view,因此它并没有真正地在内存中扁平化。因此,“扁平化视图”被索引并设置为 NaN,同时仍保持为 2D 数组。 - Divakar
谢谢,我一边看文档一边回复你 :). 作为最后的好奇,ravel() 的文档中说“只有在需要时才会创建副本。”。那么我会得到一个扁平化的 A 吗? - Oleg
1
如果只是进行索引,它必须保持为2D数组。您还可以使用np.put来达到同样的效果。因此,使用它的解决方案将是np.put(A,np.random.choice(A.size, c, replace=False),np.nan) - Divakar

9

您可以使用np.random.shuffle在新数组上创建掩码:

import numpy as np

M = 10;
N = 5;
c = 15;
A = np.random.randn(M,N)

mask=np.zeros(M*N,dtype=bool)
mask[:c] = True
np.random.shuffle(mask)
mask=mask.reshape(M,N)

A[mask] = np.nan

这将会得到:

[[ 0.98244168  0.72121195  0.99291217  0.17035834  0.46987918]
 [ 0.76919975  0.53102064         nan  0.78776918         nan]
 [ 0.50931304  0.91826809  0.52717345         nan         nan]
 [ 0.35445471  0.28048106  0.91922292  0.76091783  0.43256409]
 [ 0.69981284  0.0620876   0.92502572         nan         nan]
 [        nan         nan         nan  0.24466688  0.70259211]
 [ 0.4916004          nan         nan  0.94945378  0.73983538]
 [ 0.89057404  0.4542628          nan  0.95547377         nan]
 [ 0.4071912   0.36066797  0.73169132  0.48217226  0.62607888]
 [ 0.30341337         nan  0.75608859  0.31497997         nan]]

1
你的方法也不错!我不得不通过谷歌搜索来实现无重复随机选择,并发现random_choice有一个可选的replace参数,直接就可以用了! :) - Divakar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接