[Numpy] 数组广播的两个例题:找零问题,最近邻居问题

找零问题

25分分成10分,5分和1分怎么分呢?有多少种分法?
Using broadcasting, compute the number of ways a quarter (i.e., 25 cents) can be split into pennies, nickels, and dimes.

Hint: You can do this using loops as

n=0 # start counter
for n_d in range(0,3): # at most 2 dimes
for n_n in range(0,6): # at most 5 nickels
for n_p in range(0,26): # at most 25 pennies
value = n_d10+n_n5+n_p
if value == 25:
print (‘dimes=%d, nickels=%d, pennies=%d’%(n_d,n_n,n_p))
n+=1
Can you find a better way using broadcasting?
Can you do it in one-line?
What is the supportability argument against this?

import numpy as np

#X as dimes, Y as nickles, Z as pennis
X=np.arange(3)*np.array([10])
Y=np.arange(6)*np.array([5])
Z=np.arange(26)

#broadcasting
res = X[:,None,None]+Y[None,:,None]+Z[None,None,:]

#Number of possible solutions 12
print(len(np.where(res==25)[0]))

#Output solutions
for iter in np.array(np.where(res==25)).T:
    print(f'{iter[0]} dimes, {iter[1]} nickles, {iter[2]} pennis.')
# result:
12
0 dimes, 0 nickles, 25 pennis.
0 dimes, 1 nickles, 20 pennis.
0 dimes, 2 nickles, 15 pennis.
0 dimes, 3 nickles, 10 pennis.
0 dimes, 4 nickles, 5 pennis.
0 dimes, 5 nickles, 0 pennis.
1 dimes, 0 nickles, 15 pennis.
1 dimes, 1 nickles, 10 pennis.
1 dimes, 2 nickles, 5 pennis.
1 dimes, 3 nickles, 0 pennis.
2 dimes, 0 nickles, 5 pennis.
2 dimes, 1 nickles, 0 pennis.

最近邻居问题

如何求出二维直角坐标系上各点相距最近的点
Using broadcasting, can you compute the nearest neighbors to the following two-dimensional array,

array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
For a given row, your answer should be the indices of the other row that is closest to it (other than itself) using the square of the Euclidean distance metric

di,j=x2i,j+y2i,j
The answer for this exercise is the following,

array([1, 0, 1, 2])
So, the point (0,1) in the 0th row is closest to (2,3) which is 1st row. The 1st row is closest to the 0th row, the 2nd row is closest to the 1st row, and the 3rd row is closest to the 2nd row.

What if you had a three-dimensional array?

参考https://stackoverflow.com/questions/52366421/how-to-do-n-d-distance-and-nearest-neighbor-calculations-on-numpy-arrays/52366706

import numpy as np

X = np.array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])

# D is the np array of distance
D = np.sqrt(np.abs(np.sum((X[None,:,:] - X[:,None,:])**2, axis=2)))

# Another way to write D
D_ds = np.sqrt(                                #  (X - Y) ** 2   
np.einsum('ij, ij ->i', X, X)[:, None] +    # = X ** 2        \
np.einsum('ij, ij ->i', X, X)          -    # + X ** 2        \
2 * X.dot(X.T))                             # - 2 * X * Y

# print(D)
# argpartition: find the 2nd small distance on second axis and then do partition
print(D.argpartition(1,axis=1)[:,1])
# result:
# D
#[[0.         2.82842712 5.65685425 8.48528137]
# [2.82842712 0.         2.82842712 5.65685425]
# [5.65685425 2.82842712 0.         2.82842712]
# [8.48528137 5.65685425 2.82842712 0.        ]]
[1 0 1 2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值