2

I have the following problem to which i haven't found any helpful hints anywhere so far.

I have two arrays which look like this:

sample_nodes = [[ ID_1    x1    y1    z1]
                [ ID_2    x2    y2    z2]
                [ ID_3    x3    y3    z4]
                .
                .
                .
                [ ID_n    xn    yn    zn]]

and

sample_elements = [[[ ID_7    0    0    0]
                    [ ID_21   0    0    0]
                    [ ID_991  0    0    0]
                    [ ID_34   0    0    0]]

                   [[ ID_67   0    0    0]
                    [ ID_1    0    0    0]
                    [ ID_42   0    0    0]
                    [ ID_15   0    0    0]]

                    .
                    .
                    .

                   [[ ID_33   0    0    0]
                    [ ID_42   0    0    0]
                    [ ID_82   0    0    0]
                    [ ID_400  0    0    0]]]

The sample_nodes has the x, y and z coordinates which are needed by the sample_elements where the IDs are arranged in a random order. So, I have to look at each ID of each row in the sample_elements array and find out the corresponding x, y and z coordinates from the sample_nodes and replace the zero values back again in the sample_elements array corresponding to the IDs.

I am very new to both python and numpy and hence, have no idea how to go about this. Thanks in advance guys for any pointers for solving this question.

Also, all he IDs in the sample_elements are present in the sample_nodes. Only in the sample_elements are they arranged in random because they are generated by a meshing software called Gmsh. I am actually trying to parse it's output mesh file.

Parvez Ahmed
  • 19
  • 2
  • 7

2 Answers2

1

You can use np.searchsorted to form the original row order and then simply indexing into sample_nodes with it would give us the desired output. Thus, we would have an implementation like so -

sample_nodes[np.searchsorted(sample_nodes[:,0],sample_elements[:,0])]

Sample run -

In [80]: sample_nodes
Out[80]: 
array([[1, 3, 3, 6],
       [3, 2, 4, 8],
       [4, 2, 3, 4],
       [5, 3, 0, 8],
       [6, 8, 2, 3],
       [7, 4, 6, 3],
       [8, 3, 8, 4]])

In [81]: sample_elements
Out[81]: 
array([[7, 0, 0, 0],
       [5, 0, 0, 0],
       [3, 0, 0, 0],
       [6, 0, 0, 0]])

In [82]: sample_nodes[np.searchsorted(sample_nodes[:,0],sample_elements[:,0])]
Out[82]: 
array([[7, 4, 6, 3],
       [5, 3, 0, 8],
       [3, 2, 4, 8],
       [6, 8, 2, 3]])

If the IDs in sample_nodes are not in sorted order, we need to use the optional argument sorter with np.searchsorted, like so -

sidx = sample_nodes[:,0].argsort()
row_idx = np.searchsorted(sample_nodes[:,0],sample_elements[:,0],sorter=sidx)
out = sample_nodes[sidx[row_idx]]

Sample run -

In [98]: sample_nodes
Out[98]: 
array([[3, 3, 3, 6],
       [5, 2, 4, 8],
       [8, 2, 3, 4],
       [1, 3, 0, 8],
       [4, 8, 2, 3],
       [7, 4, 6, 3],
       [6, 3, 8, 4]])

In [99]: sample_elements
Out[99]: 
array([[7, 0, 0, 0],
       [5, 0, 0, 0],
       [3, 0, 0, 0],
       [6, 0, 0, 0]])

In [100]: out
Out[100]: 
array([[7, 4, 6, 3],
       [5, 2, 4, 8],
       [3, 3, 3, 6],
       [6, 3, 8, 4]])
Divakar
  • 218,885
  • 19
  • 262
  • 358
1

The numpy_indexed package has a function to solve the key step of your problem (finding the indices of one sequence in another). If you are unfamiliar with numpy, and care about efficiency at all, make sure to read up on that as well!

import numpy as np
import numpy_indexed as npi

sample_nodes = np.asarray(sample_nodes)
sample_elements = np.asarray(sample_elements)

idx = npi.indices(sample_nodes[:, 0], sample_elements[:, 0])

sample_elements[:, 1:] = sample_nodes[idx, 1:]
Eelco Hoogendoorn
  • 10,459
  • 1
  • 44
  • 42
  • This also worked for me. Divakar's solution worked without needing to install a package, hence i upvoted his solution. Nevertheless, thanks a lot for taking the time out to answer. – Parvez Ahmed Jul 26 '16 at 15:11
  • You are welcome; the performance characteristics should be near identical as the other solution, and there is no arguing taste as it comes to crtl-c/crtl-v versus pip install :) – Eelco Hoogendoorn Jul 26 '16 at 17:20
  • Ha ha ha, that always seems like an easy solution doesn't it? Problem is, your tip worked on my laptop but I couldn't get it to work on my institute's PC where I have no admin privileges to install "numpy_indexed" and the admin is on vacation, now being the semester break and all. – Parvez Ahmed Jul 26 '16 at 17:32
  • ah yeah that is annoying. the answers in this thread might be helpful with that sort of thing in the future: http://stackoverflow.com/questions/14179941/how-to-install-python-packages-without-root-privileges – Eelco Hoogendoorn Jul 26 '16 at 18:13