I have a multi-classification task, and I have gotten the one-hot type predictions like
[[0, 1, 1],
[0, 1, 0],
[1, 0, 1]]
I wish to convert this one-hot vector to labels like
[[1, 2], [1], [0, 2]]
I have tried tf.argmax, but it doesn't work. So how can I deal with it?
Using list comprehensions:
oheList = [[0, 1, 1],
[0, 1, 0],
[1, 0, 1]]
[[i for i in range(len(el)) if el[i]==1] for el in oheList]
# [[1, 2], [1], [0, 2]]
Another way to solve the problem,
import numpy as np
arr = np.array([[0, 1, 1],
[0, 1, 0],
[1, 0, 1]])
result = {}
for r, c in zip(*np.where(arr == 1)):
result.setdefault(r, []).append(c)
print(result.values())
[[1, 2], [1], [0, 2]]
Related
for example I have this list:
lst = [[0, 1], [0, 1], [0, 1], [1, 0], [1, 0], [1, 0]]
and I shuffle it for example with seed = 42:
random.seed(42)
random.shuffle(lst)
I took this list after shuffle:
[[1, 0], [0, 1], [0, 1], [1, 0], [0, 1], [1, 0]]
I want to take oposite of this shuffle too
How can I take this list:
[[0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [0, 1]]
I want oposite seed
I want to be able to convert an adjacency matrix to array of edges. Currently I know only how to conver an array of edges to adjacency matrix:
E = [[0, 0], [0, 1], [1, 1], [2, 0]]
size = len(set([n for e in E for n in e]))
adjacency_matrix = [[0] * size for _ in range(size)]
for sink, source in E:
adjacency_matrix[sink][source] = 1
>> print(adjacency_matrix)
[[1, 1, 0], [0, 1, 0], [1, 0, 0]]
but is there a possibility to reverse this process?
If you need pure python, use a list comprehension:
adjacency_matrix = [[1, 1, 0], [0, 1, 0], [1, 0, 0]]
E = [[i,j] for i,l in enumerate(adjacency_matrix) for j, x in enumerate(l) if x]
output: [[0, 0], [0, 1], [1, 1], [2, 0]]
Try this
E = np.stack(np.where(adjacency_matrix)).T
Add tolist() if you want a list
Output (with tolist())
[[0, 0], [0, 1], [1, 1], [2, 0]]
EDIT: my bad I thought OP was using numpy, so here it is in numpy
Yes, it's possible and easy, just iterate through your matrix using two nested cycles, for example:
adjacency_matrix = [[1, 1, 0], [0, 1, 0], [1, 0, 0]]
E = []
for i in range(size):
for j in range(size):
if adjacency_matrix[i][j] == 1:
E.append([i, j])
print(E)
Output:
[[0, 0], [0, 1], [1, 1], [2, 0]]
You could make a function for it:
def adj_to_edges(A):
edges = []
for i,row in enumerate(A):
for j,b in enumerate(row):
if b == 1:
edges.append([i,j])
return edges
print(adj_to_edges([[1, 1, 0], [0, 1, 0], [1, 0, 0]]))
#[[0, 0], [0, 1], [1, 1], [2, 0]]
I have a list having sublists of numbers and want to extract specific ones. In my simplified example I have two main sublists and each one has its own pairs of numbers:
data=[[[1, 0], [2, 0], [2, 1], [2, 2],\
[1, 0], [1, 1], [1, 2],\
[0, 1], [0, 2], [0, 3]],\
[[1, 0], [2, 0],\
[1, 0],\
[0, 1], [0, 2], [1, 2],\
[1, 0], [1, 1], [1, 1]]]
Pairs stored in data can be divided based on some rules and I want the last pair of each division. For simplicity I have shown each division as a row in data. Each division starts with [1, 0] or [0, 1] and these two pairs are break points. Then, simply I want the last pair before each break points. In cases I may have no point between two break points and I only export the previous break point. Finally I want it as the following list:
data=[[[2, 2],\
[1, 2],\
[0, 3]],\
[[2, 0],\
[1, 0],\
[1, 2],\
[1, 1]]]
You can do the following, using enumerate:
def fun(lst):
return [p for i, p in enumerate(lst) if i==len(lst)-1 or set(lst[i+1])=={0,1}]
[*map(fun, data)]
# [[[2, 2], [1, 2], [0, 3]], [[2, 0], [1, 0], [1, 2], [1, 1]]]
fun filters a nested list for all elements that are either last or succeeded by [0, 1] or [1, 0].
data=[[[1, 0], [2, 0], [2, 1], [2, 2],
[1, 0], [1, 1], [1, 2],
[0, 1], [0, 2], [0, 3]],
[[1, 0], [2, 0],
[1, 0],
[0, 1], [0, 2], [1, 2],
[1, 0], [1, 1], [1, 1]]]
newData = []
for subarray in data:
new_subarray = []
for i,item in enumerate(subarray):
if item == [0,1] or item == [1,0]:
if i> 0:
new_subarray.append(subarray[i-1])
if i == len(subarray)-1:
new_subarray.append(item)
newData.append(new_subarray)
print(newData)
Here is a fun little unreadable numpy oneliner:
import numpy as np
[np.array(a)[np.roll(np.flatnonzero(np.logical_or(np.all(np.array(a)==(1, 0), axis=1), np.all(np.array(a)==(0, 1), axis=1)))-1, -1)].tolist() for a in data]
# [[[2, 2], [1, 2], [0, 3]], [[2, 0], [1, 0], [1, 2], [1, 1]]]
It works but in reality you'd better use schwobaseggl's solution.
Say if i have a tensor that is
value = torch.tensor([
[[0, 0, 0], [1, 1, 1]],
[[2, 2, 2], [3, 3, 3]],
])
essentially with shape (2,2,3).
Now say if i have an index = [1, 0], which means I want to take:
# row 1 of [[0, 0, 0], [1, 1, 1]], giving me: [1, 1, 1]
# row 0 of [[2, 2, 2], [3, 3, 3]], giving me: [2, 2, 2]
So that the final output:
output = torch.tensor([[1, 1, 1], [2, 2, 2]])
is there a vectorized way to achieve this?
You can use advanced indexing.
I can't find a good pytorch document about this, but I believe it works as same as numpy, so here's the numpy's document about indexing.
import torch
value = torch.tensor([
[[0, 0, 0], [1, 1, 1]],
[[2, 2, 2], [3, 3, 3]],
])
index = [1, 0]
i = range(0,2)
result = value[i, index]
# same as result = value[i, index, :]
print(result)
Using the following method:
myArray = [0,1] * NUM_ITEMS
Desired result (2d array):
[[0,1],[0,1],[0,1]...]
Actual result (extended 1d array):
[0,1,0,1,0,1...]
How can I achieve the desired result preferably without using numpy?
A list comprehension should do the trick:
>>> NUM_ITEMS = 5
>>> my_array = [[0, 1] for _ in range(NUM_ITEMS)]
>>> my_array
[[0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
Since you tagged arrays, here's an alternative numpy solution using numpy.tile.
>>> import numpy as np
>>> NUM_ITEMS = 10
>>> np.tile([0, 1], (NUM_ITEMS, 1))
array([[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1]])