[SciPy-User] 'compress' numpy array

Lutz Maibaum lutz.maibaum at gmail.com
Mon Jul 18 19:53:35 EDT 2011


On Jul 15, 2011, at 1:08 PM, Johannes Eckstein wrote:
> I have a set of faces, which I formated like this:
> [[[ 1.      -0.1     -0.     ]
>   [ 1.      -0.09921 -0.01253]
>   [ 1.      -0.      -0.     ]]
> 
>  [[ 1.      -0.1     -0.     ]
>   [ 1.      -0.2     -0.     ]
>   [ 1.      -0.09921 -0.01253]]
> 
>  [[ 1.      -0.2     -0.     ]
>   [ 1.      -0.19842 -0.02507]
>   [ 1.      -0.09921 -0.01253]]
> 
>  [[ 1.      -0.2     -0.     ]
>   [ 1.      -0.3     -0.     ]
>   [ 1.      -0.19842 -0.02507]]
> 
>  [[ 1.      -0.3     -0.     ]
>   [ 1.      -0.29763 -0.0376 ]
>   [ 1.      -0.19842 -0.02507]]
> 
>  [[ 1.      -0.3     -0.     ]
>   [ 1.      -0.4     -0.     ]
>   [ 1.      -0.29763 -0.0376 ]]
> 
>  [[ 1.      -0.4     -0.     ]
>   [ 1.      -0.39685 -0.05013]
>   [ 1.      -0.29763 -0.0376 ]]
> 
>  [[ 1.      -0.4     -0.     ]
>   [ 1.      -0.5     -0.     ]
>   [ 1.      -0.39685 -0.05013]]
> 
>  [[ 1.      -0.5     -0.     ]
>   [ 1.      -0.49606 -0.06267]
>   [ 1.      -0.39685 -0.05013]]
> 
>  [[ 1.      -0.5     -0.     ]
>   [ 1.      -0.6     -0.     ]
>   [ 1.      -0.49606 -0.06267]]
> 
>  [[ 1.      -0.6     -0.     ]
>   [ 1.      -0.59527 -0.0752 ]
>   [ 1.      -0.49606 -0.06267]]
> 
>  [[ 1.      -0.6     -0.     ]
>   [ 1.      -0.7     -0.     ]
>   [ 1.      -0.59527 -0.0752 ]]]
> 
> Now I would like to find all the redundant points and create a list from 
> them like this:
> [[ 1.      -0.1     -0.     ]
>  [ 1.      -0.09921 -0.01253]
>  [ 1.      -0.      -0.     ]
>  [ 1.      -0.2     -0.     ]
>  [ 1.      -0.19842 -0.02507]
>  ...]
> 
> Then make an array of the indices (which could be also shifted with x-1) 
> looking like this:
> [[1 2 3]
>  [1 4 2]
>  [4 5 2]
>  ...]
> 
> Anyone an Idea or a hint of how I can efficiently compute those two results?
> To me it seems like I need some kind of tricky sorting algorithm, but 
> maybee there is a trick that I don't see…

This sounds like a case for np.unique, with the caveat that your elements are 3-tuples of floats, which unique doesn't seem to handle. You could work around this by turning your points into records of 3 floats. Perhaps something like the following would work (let's call the input array you posted "input"):

In [2]: input=array([[[ 1.     , -0.1    , -0.     ],
   ...:         [ 1.     , -0.09921, -0.01253],
   ...:         [ 1.     , -0.     , -0.     ]],
   ...: 
   ...:        [[ 1.     , -0.1    , -0.     ],
   ...:         [ 1.     , -0.2    , -0.     ],
   ...:         [ 1.     , -0.09921, -0.01253]],
   ...: 
   ...:        [[ 1.     , -0.2    , -0.     ],
   ...:         [ 1.     , -0.19842, -0.02507],
   ...:         [ 1.     , -0.09921, -0.01253]],
   ...: 
   ...:        [[ 1.     , -0.2    , -0.     ],
   ...:         [ 1.     , -0.3    , -0.     ],
   ...:         [ 1.     , -0.19842, -0.02507]],
   ...: 
   ...:        [[ 1.     , -0.3    , -0.     ],
   ...:         [ 1.     , -0.29763, -0.0376 ],
   ...:         [ 1.     , -0.19842, -0.02507]],
   ...: 
   ...:        [[ 1.     , -0.3    , -0.     ],
   ...:         [ 1.     , -0.4    , -0.     ],
   ...:         [ 1.     , -0.29763, -0.0376 ]],
   ...: 
   ...:        [[ 1.     , -0.4    , -0.     ],
   ...:         [ 1.     , -0.39685, -0.05013],
   ...:         [ 1.     , -0.29763, -0.0376 ]],
   ...: 
   ...:        [[ 1.     , -0.4    , -0.     ],
   ...:         [ 1.     , -0.5    , -0.     ],
   ...:         [ 1.     , -0.39685, -0.05013]],
   ...: 
   ...:        [[ 1.     , -0.5    , -0.     ],
   ...:         [ 1.     , -0.49606, -0.06267],
   ...:         [ 1.     , -0.39685, -0.05013]],
   ...: 
   ...:        [[ 1.     , -0.5    , -0.     ],
   ...:         [ 1.     , -0.6    , -0.     ],
   ...:         [ 1.     , -0.49606, -0.06267]],
   ...: 
   ...:        [[ 1.     , -0.6    , -0.     ],
   ...:         [ 1.     , -0.59527, -0.0752 ],
   ...:         [ 1.     , -0.49606, -0.06267]],
   ...: 
   ...:        [[ 1.     , -0.6    , -0.     ],
   ...:         [ 1.     , -0.7    , -0.     ],
   ...:         [ 1.     , -0.59527, -0.0752 ]]])

In [3]: input.shape
Out[3]: (12, 3, 3)

In [4]: temp = input.ravel().view([('x', float), ('y', float), ('z', float)])

In [5]: temp.shape
Out[5]: (36,)

In [6]: uniquepoints, indices = np.unique(temp,return_inverse=True)

In [7]: uniquepoints
Out[7]: 
array([(1.0, -0.69999999999999996, -0.0),
       (1.0, -0.59999999999999998, -0.0),
       (1.0, -0.59526999999999997, -0.075200000000000003),
       (1.0, -0.5, -0.0), (1.0, -0.49606, -0.062670000000000003),
       (1.0, -0.40000000000000002, -0.0),
       (1.0, -0.39684999999999998, -0.050130000000000001),
       (1.0, -0.29999999999999999, -0.0),
       (1.0, -0.29763000000000001, -0.037600000000000001),
       (1.0, -0.20000000000000001, -0.0),
       (1.0, -0.19842000000000001, -0.025069999999999999),
       (1.0, -0.10000000000000001, -0.0),
       (1.0, -0.099210000000000007, -0.012529999999999999),
       (1.0, -0.0, -0.0)], 
      dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])

In [8]: indices.reshape(12,3)
Out[8]: 
array([[11, 12, 13],
       [11,  9, 12],
       [ 9, 10, 12],
       [ 9,  7, 10],
       [ 7,  8, 10],
       [ 7,  5,  8],
       [ 5,  6,  8],
       [ 5,  3,  6],
       [ 3,  4,  6],
       [ 3,  1,  4],
       [ 1,  2,  4],
       [ 1,  0,  2]])


Hope this helps,

  Lutz




More information about the SciPy-User mailing list