我试图通过循环来解决这个问题,但就我而言,性能也很重要。那么,有什么办法可以通过内置的numpy函数来解决这个问题?
这是我尝试的代码:
import numpy as np
np.random.seed(123)
x = np.random.uniform(0, 1, 10)
y = np.random.uniform(0, 1, 20)
C = np.arange(100).reshape(10,20)
for i in range(10):
for j in range(20):
C[i, j] = 1 / (x[i] - y[j])
print(C)
答案 0 :(得分:0)
In [158]: np.random.seed(123)
...: x = np.random.uniform(0, 1, 10)
...: y = np.random.uniform(0, 1, 20)
...:
...: C = np.arange(100).reshape(10,10)
...:
...: for i in range(10):
...: for j in range(10):
...: C[i, j] = 1 / (x[i] - y[j])
...:
无循环版本是:
In [159]: np.allclose(1/(x[:,None]-y[None,:]),C)
...
ValueError: operands could not be broadcast together with shapes (10,20) (10,10)
糟糕,该计算有效,但是会生成(10,20)数组,就像您通过仅循环y
的一部分来创建(10,10)一样:
In [160]: np.allclose(1/(x[:,None]-y[None,:10]),C)
Out[160]: False
但是为什么不匹配?让我们检查一下值:
In [161]: C
Out[161]:
array([[ 2, -30, 3, 1, 3, -24, 1, 1, 6, 6],
[ -17, -2, -6, 4, -8, -2, 9, 9, -4, -4],
[ -8, -1, -4, 5, -5, -1, 22, 19, -3, -3],
[ 4, -5, 8, 2, 6, -5, 2, 2, 50, 51],
[ 2, -104, 3, 1, 3, -53, 1, 1, 5, 5],
[ 12, -3, -64, 2, 39, -3, 4, 4, -9, -9],
[ 1, 3, 1, 1, 1, 4, 1, 1, 2, 2],
[ 2, -22, 4, 1, 3, -18, 1, 1, 6, 6],
[ 7, -4, 23, 2, 12, -3, 3, 3, -19, -19],
[ 20, -2, -21, 3, -168, -2, 4, 4, -7, -7]])
In [162]: 1/(x[:,None]-y[None,:10])
Out[162]:
array([[ 2.83052645, -30.69318553, 3.87751788, 1.57037324,
3.35092648, -24.08117081, 1.94561063, 1.91932159,
6.06362642, 6.07379914],
[ -17.53196215, -2.25779314, -6.56026315, 4.41576282,
-8.93615756, -2.21309409, 9.64807633, 9.03443739,
-4.07477972, -4.07019868],
[ -8.59648887, -1.99124547, -4.7232017 , 5.98180728,
-5.8413671 , -1.95639603, 22.54297209, 19.45536745,
-3.2819175 , -3.2789451 ],
[ 4.80453349, -5.62635579, 8.86976769, 2.03402156,
6.52441214, -5.35674196, 2.71132737, 2.66054378,
50.5985934 , 51.31578289],
[ 2.65751805, -104.37609732, 3.56002726, 1.5156313 ,
3.11114844, -53.97692265, 1.86227633, 1.83817713,
5.32148144, 5.32931481],
[ 12.51119064, -3.26858007, -64.65886011, 2.75157239,
39.90071936, -3.17572279, 4.15602154, 4.0378801 ,
-9.22127157, -9.19784432],
[ 1.56841542, 3.97275499, 1.84436525, 1.0856746 ,
1.71609023, 4.11914558, 1.25270511, 1.24175407,
2.22611632, 2.22748596],
[ 2.92695729, -22.61421767, 4.06079013, 1.59961138,
3.48692684, -18.80913104, 1.99069149, 1.96317869,
6.52407795, 6.53585581],
[ 7.25932338, -4.03034356, 23.60736785, 2.37386467,
12.06452404, -3.89008935, 3.35075535, 3.27353517,
-19.75524346, -19.64803083],
[ 20.4333914 , -2.96795626, -21.5263349 , 3.00806503,
-168.72690268, -2.89119379, 4.77040545, 4.61540389,
-7.17185934, -7.15768024]])
C
初始化为整数dtype,因此会截断所有插入的浮点值。我们可以通过以下方式获得相同的效果:
In [163]: (1/(x[:,None]-y[None,:10])).astype(int)
Out[163]:
array([[ 2, -30, 3, 1, 3, -24, 1, 1, 6, 6],
[ -17, -2, -6, 4, -8, -2, 9, 9, -4, -4],
[ -8, -1, -4, 5, -5, -1, 22, 19, -3, -3],
[ 4, -5, 8, 2, 6, -5, 2, 2, 50, 51],
[ 2, -104, 3, 1, 3, -53, 1, 1, 5, 5],
[ 12, -3, -64, 2, 39, -3, 4, 4, -9, -9],
[ 1, 3, 1, 1, 1, 4, 1, 1, 2, 2],
[ 2, -22, 4, 1, 3, -18, 1, 1, 6, 6],
[ 7, -4, 23, 2, 12, -3, 3, 3, -19, -19],
[ 20, -2, -21, 3, -168, -2, 4, 4, -7, -7]])
现在它们匹配:
In [164]: np.allclose((1/(x[:,None]-y[None,:10])).astype(int),C)
Out[164]: True
答案 1 :(得分:0)
找到了该方法fromfunction
,该方法应该可以执行您想要的操作。
import numpy as np
np.random.seed(123)
x = np.random.uniform(0, 1, 10)
y = np.random.uniform(0, 1, 20)
# for a 10 by 20 array
C = np.fromfunction(lambda i, j: 1/(x[i] - y[j]), (10, 20), dtype=int)
# for a 10 by 10 array
C = np.fromfunction(lambda i, j: 1/(x[i] - y[j]), (10, 10), dtype=int)
# to avoid defining the shape
C = np.fromfunction(lambda i, j: 1/(x[i] - y[j]), (x.size, y.size), dtype=int)
如果您要使所有整数都为整数,则只需进行C.astype(int)
等。
答案 2 :(得分:-1)
import numpy as np
np.random.seed(123)
x = np.random.uniform(0, 1, 10)
y = np.random.uniform(0, 1, 20)
# C = np.arange(100).reshape(10,10)
ln = min(x.shape[0], y.shape[0])
# this will get rid of manually defining C shape. Also works for any length of 1D x and y
C = np.reciprocal(1/(x - y.reshape((-1,1))))
# or you can also just simply do
C = 1/(x - y.reshape((-1,1)))