I have a list of coordinates like
list_cor =
[[4190091.4195999987, 7410226.618699998],
[4190033.2124999985, 7410220.0823],
[4190033.2124999985, 7410220.0823],
[4190035.7005000003, 7410208.670500003],
[4190033.2124999985, 7410220.0823],
[4190022.768599998, 7410217.844300002]]
I need to get only these values:
[[4190091.4195999987, 7410226.618699998],
[4190035.7005000003, 7410208.670500003],
[4190022.768599998, 7410217.844300002]]
Tried numpy.unique()
but it adds this item [4190033.2124999985, 7410220.0823]
, which I don't need.
Use numpy.unique
with axis
and return_counts
parameters:
arr, uniq_cnt = np.unique(list_cor, axis=0, return_counts=True)
uniq_arr = arr[uniq_cnt==1]
You're almost there :
coords=[ x+1j*y for (x,y) in list_cor] # using complex; a way for grouping
uniques,counts=np.unique(coords,return_counts=True)
res=[ [x.real,x.imag] for x in uniques[counts==1] ] # ungroup
For :
[[4190022.7685999982, 7410217.8443000019],
[4190035.7005000003, 7410208.6705000028],
[4190091.4195999987, 7410226.6186999977]]
I like using a dictionary to keep track of counts:
>>> counts = {}
>>> for coordinate in list_cor:
... coordinate = tuple(coordinate) # so it can be hashed and used as dict key
... counts.setdefault(coordinate, 0) # add coordinate to dict
... counts[coordinate] += 1 # increment count for coordinate
...
You then have a dictionary that looks like this:
>>> counts
{(4190091.4195999987, 7410226.618699998): 1, (4190033.2124999985, 7410220.0823): 3, (4190035.7005000003, 7410208.670500003): 1, (4190022.768599998, 7410217.844300002): 1}
You can then use list comprehension to create a list of unique coordinates:
>>> [list(coordinate) for coordinate, count in counts.items() if count == 1]
[[4190091.4195999987, 7410226.618699998], [4190035.7005000003, 7410208.670500003], [4190022.768599998, 7410217.844300002]]
If you're fine leaving the coordinates as tuples, you can replace list(coordinate)
with coordinate
.
In simple pure python basic types:
# transform to tuples
list_cor=[tuple(c) for c in list_cor]
# transform back after using set to select unique elements only
list_cor_unique=[list(l) for l in list(set(list_cor))]
# create a copy
list_cor_more_than_once = [i for i in list_cor]
# drop all the elements appearing only once
[list_cor_more_than_once.remove(tuple(l)) for l in list_cor_unique if tuple(l) in list_cor]
# finally, keep the uniques not appearing more than once
list_cor_unique=[l for l in list_cor_unique if (tuple(l) in list_cor) and (not (tuple(l) in list_cor_more_than_once)) ]
Pros:
no external libraries
would work for higher dimension coordinates
For older version of numpy that don't have the return_counts
parameter, you could help yourself with collections.Counter
:
>>> list_cor = np.array(list_cor) # assuming list_cor is a numpy array
>>> counts = collections.Counter(map(tuple, list_cor))
>>> counts_arr = np.array([counts[tuple(x)] for x in list_cor])
>>> list_cor[counts_arr == 1]
array([[ 4190091.4196, 7410226.6187],
[ 4190035.7005, 7410208.6705],
[ 4190022.7686, 7410217.8443]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With