Related
During communities' detection I am trying to remove duplicates nodes from lists of lists (aimed to calculate ARI).
What I have – few dozen lists inside one list with different dimensions:
lst_of_lts= [[5192, 32896, 34357, 34976, 36683, 43315], … ,[19, 92585, 94137, 98381, 99041, 100395, 101100, 109759]]
What I am running:
import itertools
Lst_of_lts.sort()
Lst_of_lts_2 = list(k for k,_ in itertools.groupby(Lst_of_lts))
Lst_of_lts_nodops= [list(i) for i in {tuple(sorted(i)) for i in Lst_of_lts_2}]
For some reason, it doesn’t remove duplicates.
The dimensions remain the same-
Any suggestions?
Also tried many options such as:
Remove duplicate items from lists in Python lists and
Remove duplicated lists in list of lists in Python
If you are removing duplicates just in the list itself, you can use set.
a = np.random.randint(0,5,(10,10)).tolist()
a
Out[128]:
[[0, 3, 0, 2, 4, 4, 0, 0, 3, 3],
[2, 4, 0, 2, 4, 2, 2, 4, 3, 1],
[3, 2, 0, 1, 2, 0, 2, 0, 2, 1],
[3, 1, 4, 1, 0, 1, 4, 4, 3, 4],
[2, 0, 1, 1, 0, 4, 1, 4, 2, 3],
[0, 0, 1, 3, 4, 3, 1, 3, 0, 1],
[1, 2, 0, 2, 1, 3, 4, 2, 2, 0],
[3, 3, 2, 2, 0, 4, 1, 1, 0, 0],
[0, 1, 3, 0, 4, 4, 2, 1, 1, 4],
[0, 1, 4, 4, 0, 1, 3, 2, 1, 1]]
[list(set(i)) for i in a]
Out[129]:
[[0, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3],
[0, 1, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]
Or if you want to preserve the order of the element, you can use dict.fromkeys
[list(dict.fromkeys(i)) for i in a]
Out[133]:
[[0, 3, 2, 4],
[2, 4, 0, 3, 1],
[3, 2, 0, 1],
[3, 1, 4, 0],
[2, 0, 1, 4, 3],
[0, 1, 3, 4],
[1, 2, 0, 3, 4],
[3, 2, 0, 4, 1],
[0, 1, 3, 4, 2],
[0, 1, 4, 3, 2]]
This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 1 year ago.
I am using python, I have a nested list like this
sequences_list = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
I want to get a sort of sequences like this
sequences_list = [[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5]]
this is my code
k = 1
j = 0
while (k <= len(sequences_list)):
del sequences_list[j][k:]
k = k+1
j = j+1
print(sequences_list)
the result i get is
[[0], [0], [0], [0], [0], [0]]
Try this one
sequences_list = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
print([element[0:po+1] for po,element in enumerate(sequences_list)])
Say I have a tensor and index:
x = torch.tensor([1,2,3,4,5])
idx = torch.tensor([0,2,4])
If I want to select all elements not in the index, I can manually define a Boolean mask like so:
mask = torch.ones_like(x)
mask[idx] = 0
x[mask]
is there a more elegant way of doing this?
i.e. a syntax where I can directly pass the indices as opposed to creating a mask e.g. something like:
x[~idx]
I couldn't find a satisfactory solution to finding the complement of a multi-dimensional tensor of indices and finally implemented my own. It can work on cuda and enjoys fast parallel computation.
def complement_idx(idx, dim):
"""
Compute the complement: set(range(dim)) - set(idx).
idx is a multi-dimensional tensor, find the complement for its trailing dimension,
all other dimension is considered batched.
Args:
idx: input index, shape: [N, *, K]
dim: the max index for complement
"""
a = torch.arange(dim, device=idx.device)
ndim = idx.ndim
dims = idx.shape
n_idx = dims[-1]
dims = dims[:-1] + (-1, )
for i in range(1, ndim):
a = a.unsqueeze(0)
a = a.expand(*dims)
masked = torch.scatter(a, -1, idx, 0)
compl, _ = torch.sort(masked, dim=-1, descending=False)
compl = compl.permute(-1, *tuple(range(ndim - 1)))
compl = compl[n_idx:].permute(*(tuple(range(1, ndim)) + (0,)))
return compl
Example:
>>> import torch
>>> a = torch.rand(3, 4, 5)
>>> a
tensor([[[0.7849, 0.7404, 0.4112, 0.9873, 0.2937],
[0.2113, 0.9923, 0.6895, 0.1360, 0.2952],
[0.9644, 0.9577, 0.2021, 0.6050, 0.7143],
[0.0239, 0.7297, 0.3731, 0.8403, 0.5984]],
[[0.9089, 0.0945, 0.9573, 0.9475, 0.6485],
[0.7132, 0.4858, 0.0155, 0.3899, 0.8407],
[0.2327, 0.8023, 0.6278, 0.0653, 0.2215],
[0.9597, 0.5524, 0.2327, 0.1864, 0.1028]],
[[0.2334, 0.9821, 0.4420, 0.1389, 0.2663],
[0.6905, 0.2956, 0.8669, 0.6926, 0.9757],
[0.8897, 0.4707, 0.5909, 0.6522, 0.9137],
[0.6240, 0.1081, 0.6404, 0.1050, 0.6413]]])
>>> b, c = torch.topk(a, 2, dim=-1)
>>> b
tensor([[[0.9873, 0.7849],
[0.9923, 0.6895],
[0.9644, 0.9577],
[0.8403, 0.7297]],
[[0.9573, 0.9475],
[0.8407, 0.7132],
[0.8023, 0.6278],
[0.9597, 0.5524]],
[[0.9821, 0.4420],
[0.9757, 0.8669],
[0.9137, 0.8897],
[0.6413, 0.6404]]])
>>> c
tensor([[[3, 0],
[1, 2],
[0, 1],
[3, 1]],
[[2, 3],
[4, 0],
[1, 2],
[0, 1]],
[[1, 2],
[4, 2],
[4, 0],
[4, 2]]])
>>> compl = complement_idx(c, 5)
>>> compl
tensor([[[1, 2, 4],
[0, 3, 4],
[2, 3, 4],
[0, 2, 4]],
[[0, 1, 4],
[1, 2, 3],
[0, 3, 4],
[2, 3, 4]],
[[0, 3, 4],
[0, 1, 3],
[1, 2, 3],
[0, 1, 3]]])
>>> al = torch.cat([c, compl], dim=-1)
>>> al
tensor([[[3, 0, 1, 2, 4],
[1, 2, 0, 3, 4],
[0, 1, 2, 3, 4],
[3, 1, 0, 2, 4]],
[[2, 3, 0, 1, 4],
[4, 0, 1, 2, 3],
[1, 2, 0, 3, 4],
[0, 1, 2, 3, 4]],
[[1, 2, 0, 3, 4],
[4, 2, 0, 1, 3],
[4, 0, 1, 2, 3],
[4, 2, 0, 1, 3]]])
>>> al, _ = al.sort(dim=-1)
>>> al
tensor([[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]],
[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]],
[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]])
You may want to try the single-line expression:
x[np.setdiff1d(range(len(x)), idx)]
Though it seems also not elegant:).
I have a list of list where the sublist contains numbers that are either 0, 1 or 2.
I need to remove any sublist where any of the numbers are 0.
I tried this code:
l = [list(b) for b in x.Branches]
z = 0
list2 = filter(z, l)
print list2
But it keeps telling me that int is not iterable. the first line gets me my list from rhino grasshopper data, and my list is
[[1, 1, 2, 0], [0, 2, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 0], [0, 2, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 0], [0, 2, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 0], [0, 2, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 0], [0, 2, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 0, 2], [2, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 0, 2], [2, 0, 0, 2], [2, 0, 0, 0], [0, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 0, 2], [2, 0, 0, 2], [2, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 2, 2], [2, 2, 2, 2], [2, 2, 0, 2], [2, 0, 0, 2], [2, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 0, 2], [2, 0, 0, 2], [2, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
filter takes function as first argument, I actually got TypeError. That's because 0 is not a function and it is not callable.
In [49]: list(filter(0, l))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-49-fe89c490c585> in <module>
----> 1 list(filter(0, l))
TypeError: 'int' object is not callable
the way I tried is below, hope it helps
In [50]: is_zero = lambda x: x == 0
In [51]: is_all_zero = lambda x: all(map(is_zero, x))
In [52]: not_is_all_zero = lambda x: not is_all_zero(x)
is_zero checks if x is zero
is_all_zero checks if list is all zero
not_is_all_zero get opposite output of is_all_zero
and now we can use not_is_all_zero to filter l
In [54]: list(filter(not_is_all_zero, l))
Out[54]:
[[1, 1, 2, 0],
[0, 2, 2, 0],
[0, 2, 0, 0],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 0],
[0, 2, 2, 0],
[0, 2, 0, 0],
[1, 1, 2, 2],
...
Update
you want filter any of item is zero, so you can apply below function to filter the list
In [55]: is_any_zero = lambda x: any(map(is_zero, x))
In [56]: is_any_zero([0,1])
Out[56]: True
In [57]: is_any_zero([1,1])
Out[57]: False
In [59]: not_is_any_zero = lambda x: not is_any_zero(x)
In [60]: list(filter(not_is_any_zero, l))
Out[60]:
[[1, 1, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[1, 1, 2, 2],
[2, 2, 2, 2]]
To remove lists containing at least one zero, you could use
res = [ls for ls in lst if 0 not in ls]
Here is a hacky way of removing all suslists consisting only of zeros, assuming all elements are non-negative:
res = filter(sum, lst)
This uses the fact that bool(0) == False and bool(x) == True for x > 0.
Another approach to accomplish the same task is this:
list_2 = list(filter(all, l))
Here, the all function evaluates to true if every element being evaluated is true. Since bool(x) is true for all non-zero values, all(l) is true if all values in l are non-zero.
This is my current matrix:
[[0, 1, 2, 4],
[0, 3, 1, 3],
[0, 2, 3, 2],
[0, 2, 4, 1],
[0, 4, 1, 2],
[0, 3, 2, 2],
[1, 2, 2, 2]]
I want to transpose it and get this as output:
[[0, 0, 0, 0, 1],
[2, 2, 4, 3, 2],
[3, 4, 1, 2, 2],
[2, 1, 2, 2, 2]]
I used inverse = np.swapaxes(ate,0,7) but I am not sure what will be my axis2 value be. Here the axis2 is 7.
I think what you're looking for is np.transpose()
You can use np.swapaxes, however this swaps "dimensions", so for a matrix that's either 0 or 1 because you have two dimensions:
>>> np.swapaxes(arr, 0, 1) # assuming your matrix is called arr
array([[0, 0, 0, 0, 0, 0, 1],
[1, 3, 2, 2, 4, 3, 2],
[2, 1, 3, 4, 1, 2, 2],
[4, 3, 2, 1, 2, 2, 2]])
To get your desired output you'd need to remove the first two columns before the swapaxes:
>>> np.swapaxes(arr[2:], 0, 1)
array([[0, 0, 0, 0, 1],
[2, 2, 4, 3, 2],
[3, 4, 1, 2, 2],
[2, 1, 2, 2, 2]])
However generally you should use np.transpose or .T if you want to transpose the matrix/array:
>>> arr[2:].T
array([[0, 0, 0, 0, 1],
[2, 2, 4, 3, 2],
[3, 4, 1, 2, 2],
[2, 1, 2, 2, 2]])