Question: I have a strange situation here. I have that table structure

[![enter image description here](https://i.stack.imgur.com/Vv50a.png)](https://i.stack.imgur.com/Vv50a.png)

Whenever Cost is 0 I need to put Line 2 description together with Line 1 description.

I should get this at the end

[![enter image description here](https://i.stack.imgur.com/rgYD5.png)](https://i.stack.imgur.com/rgYD5.png)

I am trying to do this in c# but failing miserably.

So far, this is where I am at

[![enter image description here](https://i.stack.imgur.com/ZDcd7.png)](https://i.stack.imgur.com/ZDcd7.png)

Answer: 
Numpy's ufuncs all have an [`outer`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.outer.html?highlight=outer#numpy.ufunc.outer) method to perform operations "cross-wise" on two arrays. So to avoid most intermediate calculation and vectorize as far as possible:

```
def f(M, a):
    return 2 * M / np.add.outer(a, a)

```

---

**Answer for the old version of the question (left, because it's still useful)**:

For such things, I found it best to always work in steps, and try to find the right [`einsum`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.einsum.html?highlight=einsum#numpy.einsum) expression.

```
# the definition given in the original question,
# before the z / (y + x) update
def f0():
    d = np.empty((3,3))
    for i in range(len(a)):
        x = a[i]
        for j in range(len(a)):
            y = a[j]
            z = M[i][j]
            d[i][j] = 2 * x/(y+z)
    return d

# rewrite things inlined
def f1():
    d = np.empty((3,3))
    for i in range(len(a)):
        for j in range(len(a)):
            d[i, j] = 2 * a[i]/(a[j] + M[i, j])
    return d

# factor out broadcasting
def f2():
    d = np.empty((3,3))
    for i in range(len(a)):
        m = a + M[i, :]
        for j in range(len(a)):
            d[i,j] = 2 * a[i]/m[j]
    return d

# more broadcasting
def f3():
    d = np.empty((3,3))
    m = a + M
    for i in range(len(a)):
        for j in range(len(a)):
            d[i,j] = 2 * a[i]/m[i,j]
    return d

# now turn loops into einsums
def f4():
    d = np.empty((3,3))
    m = 1/(a + M)
    d[:,:] = 2 * np.einsum('i,ij->ij', a, m)
    return d

# collect everything
def f5():
    return np.einsum('i,ij->ij', a, 2 / (a + M))

```
With a pair of sample arrays (you should have provided these):

```
In [196]: a = np.arange(1,4); M = np.arange(1,10).reshape(3,3)                                                       
In [197]: a                                                                                                          
Out[197]: array([1, 2, 3])
In [198]: M                                                                                                          
Out[198]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
In [199]: d = 2 * M/(a[:,None]+a[None,:])                                                                            
In [200]: d                                                                                                          
Out[200]: 
array([[1.        , 1.33333333, 1.5       ],
       [2.66666667, 2.5       , 2.4       ],
       [3.5       , 3.2       , 3.        ]])

```

The `a[None,:]` could be simplified to `a`, but I wanted to clarify the broadcasting use to calculate this outer product. There are various tools in numpy for do this. I like the `None` indexing because it is simple and idiomatic.

testing against your code (again, you should have provided such a result):

```
In [202]: def foo(a): 
     ...:     d = np.zeros((3,3)) 
     ...:     for i in range(len(a)): 
     ...:         x = a[i] 
     ...:         for j in range(len(a)): 
     ...:             y = a[j] 
     ...:             z = M[i][j] 
     ...:             d[i][j] = 2 * z/(y+x) 
     ...:     return d 
     ...:                                                                                                            
In [203]: foo(a)                                                                                                     
Out[203]: 
array([[1.        , 1.33333333, 1.5       ],
       [2.66666667, 2.5       , 2.4       ],
       [3.5       , 3.2       , 3.        ]])

```