You can use np.where. First, let's make some toy data (BTW, it helps if you do this part of it yourself):
>>> h = np.random.random((3,4))
>>> nodata = 10
>>> h.flat[[2,3,4,7,8,9]] = 10
>>> ibound = np.random.randint(0,2,(3,4))
>>> L1TopOld = np.ones((3,4))*5
>>> h
array([[ 0.1382408 , 0.7718657 , 10. , 10. ],
[ 10. , 0.5595833 , 0.83703255, 10. ],
[ 10. , 10. , 0.79473842, 0.91882331]])
>>> ibound
array([[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 1, 0, 1]])
>>> L1TopOld
array([[ 5., 5., 5., 5.],
[ 5., 5., 5., 5.],
[ 5., 5., 5., 5.]])
>>> eps = 0.01
Now we can decide which ones we want to patch:
>>> ibound & (abs(h-nodata) <= eps)
array([[0, 0, 1, 0],
[0, 0, 0, 0],
[0, 1, 0, 0]])
and use this to tell np.where where we want to switch:
>>> np.where(ibound & (abs(h - nodata) <= eps), L1TopOld, h)
array([[ 0.1382408 , 0.7718657 , 5. , 10. ],
[ 10. , 0.5595833 , 0.83703255, 10. ],
[ 10. , 5. , 0.79473842, 0.91882331]])
As pointed out in the comments, this assumes that ibound is a mask consisting only of 0 and 1. If you really only want to change the cases where ibound == 1 (and not 2, for example), that's easy too:
>>> np.where((ibound == 1) & (abs(h - nodata) <= eps), L1TopOld, h)
array([[ 0.1382408 , 0.7718657 , 5. , 10. ],
[ 10. , 0.5595833 , 0.83703255, 10. ],
[ 10. , 5. , 0.79473842, 0.91882331]])
(which gives the same answer here because 0 and 1 were the only numbers in ibound.)