0

I'm struggling to find a quick way to convert a list of lists to an array of pairs. The first value of the pair is the index of the list row and the second value is made up of each value in the list for that list row. If the row is an empty list then no pair exists and should not be created.

I'm looking to get something similar to the result obtained via :

    combarray = numpy.concatenate((t1, t2), axis=0)
    tree   = cKDTree(combarray)
    pairlist  = tree.query_pairs(r = distance )
    pairs  = numpy.array(list(pairlist))
    points = len(t1)
    check = numpy.logical_and(pairs[:,0] < points, pairs[:,1] >= points)
    validpairs = pairs[check]
    validpairs[:,1] -= points

unfortunately the combining of the two arrays of points causes the main tree.query_pairs call to take approx twice as long as using t1tree.query_ball_tree(t2tree,r = distance) due to size of the combined two arrays. If I can convert the result from the KDTree.query ball back to a pair array efficiently then it may be the faster option to use.

t1 is a set of vertex points in 3d and t2 is a different set of vertex points in 3d. distance is a parameter to establish 'near' points some of which will have the same vertex value i.e. I am using a value currently of 0.02. tha main point here though is to convert the list of lists eg

row 0 : []
row 1 : [ 3, 5]
row 2 : [ 1 ]
row 3 : []
row 4 : [ 2 ]

to an array of pairs : [[1,3], [1,5], [2,1], [4,2]]

Most rows will be empty and generally there is only likely to be a few (elements in each row i.e. probably up to 20 but its an unknown). Each set of t1 and t2 values may be from 3 to around 3000 values.

hivert
  • 10,579
  • 3
  • 31
  • 56
user1942439
  • 157
  • 1
  • 8
  • Help us help you. Please can you provide a complete example: Add the import statements, add example data for `t1` and `t2` and `ntripoints`. Make it so we can copy, paste and run the code without any guesswork or modifications. – YXD Feb 19 '14 at 15:05
  • Hi, I've added more info and corrected the tripoints bit. I don't really generate tons of test data so not good at that bit. Main thing is the conversion of the list of lists so hope that's understandable now. – user1942439 Feb 19 '14 at 15:27
  • 1
    @user1942439 Some minimal data would really help. – Fred Foo Feb 19 '14 at 15:36
  • 1
    _"tha main point here thoguh is to convert the list of lists eg... to an array of pairs : (1,3), (1,5) (2,1)"_. I'm confused. Where did that 2 come from? Can you explain in more detail what you mean by "convert"? – Kevin Feb 19 '14 at 15:37
  • @user1942439 [here is an example](http://stackoverflow.com/q/21269833/553404) of how to ask a question like this. That code will run directly on my machine. You should provide data as *as Python code* by generating it randomly or typing it directly (e.g. `np.array([1, 2, 3])`). – YXD Feb 19 '14 at 15:39
  • In reply to my own comment: In each tuple, the first element refers to a row index from the input. 2 is the index of the list that contains the element 1. – Kevin Feb 19 '14 at 15:45
  • Thanks Kevin, that's what I was after other than not as a tuple ie an array of (xpairs, 2) – user1942439 Feb 19 '14 at 16:04
  • @Mr E - OK will try harder next time. In the mean time Kevin seems to of understood and solved my problem for me. – user1942439 Feb 19 '14 at 16:27
  • Glad it got sorted. It's really just about making sure you get a good answer and that people can understand what's going on, rather than being pedantic! – YXD Feb 19 '14 at 16:36

1 Answers1

1
data = [
[],
[3,5],
[1]
]

pairs = []
for row_idx, row in enumerate(data):
    for item in row:
        pairs.append((row_idx, item))

print pairs

Result:

[(1, 3), (1, 5), (2, 1)]

Alternatively, this one-liner will produce the same output:

pairs = [(row_idx, item) for row_idx, row in enumerate(data) for item in row]
Kevin
  • 74,910
  • 12
  • 133
  • 166