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: 
Apart from numpy-vectorization using Numba would also a simple and performant method, to speed up code with loops.
**Example**

```
import numpy as np
import numba as nb

@nb.njit(fastmath=True,error_model="numpy",parallel=True)
def calc(a,M):
    d=np.empty((a.shape[0],a.shape[0]))
    for i in nb.prange(a.shape[0]):
        x = a[i]
        for j in range(a.shape[0]):
            y = a[j]
            z = M[i,j]
            d[i,j] = 2. * z/(y+x)
    return d

```

**Timings**

```
M=np.random.rand(200,200)
a=np.random.rand(200)

d=calc(a,M) #first call takes longer due to compilation overhead
%timeit d=calc(a,M)
#parallel=True there is only quite limited speedup because of the small problem (200x200)
#11 µs ± 51 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
#parallel=False
#21.2 µs ± 191 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

#pure numpy solution (hpaulj)
%timeit d = 2 * M/(a[:,None]+a[None,:])
#75.7 µs ± 386 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

#without compilation
#20.8 ms ± 500 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

```
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.        ]])

```