Python 中的稀疏随机矩阵,其范围不同于 [0,1]
Sparse random matrix in Python with different range than [0,1]
我需要在 Python 中生成一个稀疏随机矩阵,所有值都在 [-1,1]
范围内且分布均匀。最有效的方法是什么?
我有一个基本的稀疏随机矩阵:
from scipy import sparse
from numpy.random import RandomState
p = sparse.rand(10, 10, 0.1, random_state=RandomState(1))
这给了我 [0,1]
中的值:
print p
(0, 0) 0.419194514403
(0, 3) 0.0273875931979
(1, 4) 0.558689828446
(2, 7) 0.198101489085
(3, 5) 0.140386938595
(4, 1) 0.204452249732
(4, 3) 0.670467510178
(8, 1) 0.878117436391
(9, 0) 0.685219500397
(9, 3) 0.417304802367
最好有一个就地解决方案或不需要将其放大为完整矩阵的解决方案,因为在实践中我将使用非常大的维度。令我惊讶的是,没有为 sparse.rand
本身设置一些快速参数。
看起来您想要的功能大约是两个月前添加的,并且将在 scipy 0.16 中可用:https://github.com/scipy/scipy/blob/77af8f44bef43a67cb14c247bc230282022ed0c2/scipy/sparse/construct.py#L671
您将能够调用 sparse.random(10, 10, 0.1, random_state=RandomState(1), data_fvs=func)
where func
"should take a single argument specifying the length of the ndarray that it will return. The structurally nonzero entries of the sparse random matrix will be taken from the array sampled by this function." 因此您将能够提供任意分布以供采样.
现在,您至少可以通过将 p 乘以标量 N 将均匀分布拉伸到 [0,N]:
>>> print 2*p
(0, 0) 0.838389028807
(9, 0) 1.37043900079
(4, 1) 0.408904499463
(8, 1) 1.75623487278
(0, 3) 0.0547751863959
(4, 3) 1.34093502036
(9, 3) 0.834609604734
(1, 4) 1.11737965689
(3, 5) 0.28077387719
(2, 7) 0.39620297817
你不能添加标量,但作为一个技巧,你可以创建一个稀疏矩阵,其中所有元素都在 p.ceil()
的非零元素中,因为 p 的所有元素都是在 [0 ,1]。然后将均匀分布转换为 [-1,1] 你可以做
print 2*p - p.ceil()
(0, 0) -0.161610971193
(0, 3) -0.945224813604
(1, 4) 0.117379656892
(2, 7) -0.60379702183
(3, 5) -0.71922612281
(4, 1) -0.591095500537
(4, 3) 0.340935020357
(8, 1) 0.756234872782
(9, 0) 0.370439000794
(9, 3) -0.165390395266
所以一般来说,如果你需要一些间隔 [a,b],只需执行:
p = (b - a)*p + a*p.ceil()
除了编写自己的类似于 sparse.rand
的构造函数之外,目前我看不到更好的解决方案,但我很想知道是否有人至少知道绕过 ceil()
破解。
由于 sparse.rand
生成一个 coo
矩阵(默认情况下),您可以直接操作其 .data
属性。 ('csr'格式可以这样转换)
p=sparse.rand(10,10,0.1)
p.data *=2
p.data -=1
之前和之后的值将是:
(0, 4) 0.758811389117
(1, 8) 0.703514506105
(1, 9) 0.640418745353
(4, 0) 0.896198785835
(4, 6) 0.511459880587
(5, 2) 0.580048680358
(7, 1) 0.739418689993
(8, 3) 0.506395207688
(8, 5) 0.900696518461
(9, 4) 0.474014207942
(0, 4) 0.517622778234
(1, 8) 0.40702901221
(1, 9) 0.280837490706
(4, 0) 0.79239757167
(4, 6) 0.0229197611736
(5, 2) 0.160097360716
(7, 1) 0.478837379986
(8, 3) 0.0127904153758
(8, 5) 0.801393036923
(9, 4) -0.051971584115
相同的空间密度,只是不同的值分布。
事实上,您可以生成全新的 .data
值。 sparse.rand
的结尾是:
....
j = .... # tweak random values
i = ... # tweak ints
vals = random_state.rand(k).astype(dtype)
return coo_matrix((vals, (i, j)), shape=(m, n)).asformat(format)
随机数组由 3 个随机序列生成,其中 2 个生成正确形状范围内的整数,第三个生成随机值。
例如从列表中选择的随机值:
In [209]: p.data=np.random.choice(np.arange(20)-10,len(p.data))/10
In [210]: print(p.A)
[[ 0. 0. 0. 0. 0.9 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. -0.1 -0.7]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[-1. 0. 0. 0. 0. 0. -0.8 0. 0. 0. ]
[ 0. 0. 0.5 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0.5 0. 0.4 0. 0. 0. 0. ]
[ 0. 0. 0. 0. -0.8 0. 0. 0. 0. 0. ]]
开发代码只是将第2行到最后一行改为:
vals = data_rvs(k).astype(dtype)
其中 data_rvs
是参数(或默认 randomstate.rand
)。
我需要在 Python 中生成一个稀疏随机矩阵,所有值都在 [-1,1]
范围内且分布均匀。最有效的方法是什么?
我有一个基本的稀疏随机矩阵:
from scipy import sparse
from numpy.random import RandomState
p = sparse.rand(10, 10, 0.1, random_state=RandomState(1))
这给了我 [0,1]
中的值:
print p
(0, 0) 0.419194514403
(0, 3) 0.0273875931979
(1, 4) 0.558689828446
(2, 7) 0.198101489085
(3, 5) 0.140386938595
(4, 1) 0.204452249732
(4, 3) 0.670467510178
(8, 1) 0.878117436391
(9, 0) 0.685219500397
(9, 3) 0.417304802367
最好有一个就地解决方案或不需要将其放大为完整矩阵的解决方案,因为在实践中我将使用非常大的维度。令我惊讶的是,没有为 sparse.rand
本身设置一些快速参数。
看起来您想要的功能大约是两个月前添加的,并且将在 scipy 0.16 中可用:https://github.com/scipy/scipy/blob/77af8f44bef43a67cb14c247bc230282022ed0c2/scipy/sparse/construct.py#L671
您将能够调用 sparse.random(10, 10, 0.1, random_state=RandomState(1), data_fvs=func)
where func
"should take a single argument specifying the length of the ndarray that it will return. The structurally nonzero entries of the sparse random matrix will be taken from the array sampled by this function." 因此您将能够提供任意分布以供采样.
现在,您至少可以通过将 p 乘以标量 N 将均匀分布拉伸到 [0,N]:
>>> print 2*p
(0, 0) 0.838389028807
(9, 0) 1.37043900079
(4, 1) 0.408904499463
(8, 1) 1.75623487278
(0, 3) 0.0547751863959
(4, 3) 1.34093502036
(9, 3) 0.834609604734
(1, 4) 1.11737965689
(3, 5) 0.28077387719
(2, 7) 0.39620297817
你不能添加标量,但作为一个技巧,你可以创建一个稀疏矩阵,其中所有元素都在 p.ceil()
的非零元素中,因为 p 的所有元素都是在 [0 ,1]。然后将均匀分布转换为 [-1,1] 你可以做
print 2*p - p.ceil()
(0, 0) -0.161610971193
(0, 3) -0.945224813604
(1, 4) 0.117379656892
(2, 7) -0.60379702183
(3, 5) -0.71922612281
(4, 1) -0.591095500537
(4, 3) 0.340935020357
(8, 1) 0.756234872782
(9, 0) 0.370439000794
(9, 3) -0.165390395266
所以一般来说,如果你需要一些间隔 [a,b],只需执行:
p = (b - a)*p + a*p.ceil()
除了编写自己的类似于 sparse.rand
的构造函数之外,目前我看不到更好的解决方案,但我很想知道是否有人至少知道绕过 ceil()
破解。
由于 sparse.rand
生成一个 coo
矩阵(默认情况下),您可以直接操作其 .data
属性。 ('csr'格式可以这样转换)
p=sparse.rand(10,10,0.1)
p.data *=2
p.data -=1
之前和之后的值将是:
(0, 4) 0.758811389117
(1, 8) 0.703514506105
(1, 9) 0.640418745353
(4, 0) 0.896198785835
(4, 6) 0.511459880587
(5, 2) 0.580048680358
(7, 1) 0.739418689993
(8, 3) 0.506395207688
(8, 5) 0.900696518461
(9, 4) 0.474014207942
(0, 4) 0.517622778234
(1, 8) 0.40702901221
(1, 9) 0.280837490706
(4, 0) 0.79239757167
(4, 6) 0.0229197611736
(5, 2) 0.160097360716
(7, 1) 0.478837379986
(8, 3) 0.0127904153758
(8, 5) 0.801393036923
(9, 4) -0.051971584115
相同的空间密度,只是不同的值分布。
事实上,您可以生成全新的 .data
值。 sparse.rand
的结尾是:
....
j = .... # tweak random values
i = ... # tweak ints
vals = random_state.rand(k).astype(dtype)
return coo_matrix((vals, (i, j)), shape=(m, n)).asformat(format)
随机数组由 3 个随机序列生成,其中 2 个生成正确形状范围内的整数,第三个生成随机值。
例如从列表中选择的随机值:
In [209]: p.data=np.random.choice(np.arange(20)-10,len(p.data))/10
In [210]: print(p.A)
[[ 0. 0. 0. 0. 0.9 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. -0.1 -0.7]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[-1. 0. 0. 0. 0. 0. -0.8 0. 0. 0. ]
[ 0. 0. 0.5 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0.5 0. 0.4 0. 0. 0. 0. ]
[ 0. 0. 0. 0. -0.8 0. 0. 0. 0. 0. ]]
开发代码只是将第2行到最后一行改为:
vals = data_rvs(k).astype(dtype)
其中 data_rvs
是参数(或默认 randomstate.rand
)。