PyTorch transferring index to 1-0 - pytorch

How to quickly set the elements in the given index list to 1 and others to 0?
For example,I have an ID pool like:
torch.arange(10),
for a given input index tensor([1,5,7,9,2]) wanna return tensor([0,1,1,0,0,1,0,1,0,1])

Easiest is to start with zeros and fill with ones using fancy indexing like this:
import torch
tensor = torch.zeros(10)
tensor[[1, 5, 7, 9, 2]] = 1
If your IDs are predefined (e.g. torch.arange(10)) and you want to get only those elements which are not zero you can do this:
import torch
ids = torch.arange(10)
mask = torch.zeros_like(ids).bool() # it has to be bool
mask[[1, 5, 7, 9, 2]] = True
torch.masked_select(ids, mask)
Which would give you:
tensor([1, 2, 5, 7, 9])

Related

Pair wise permutation of two lists in Python

I have a list with 10 numerical values. I want to return all possible combination of this list such that each element can take value +/- element value.
The approach I had in mind was to take a binary variable which takes in value from 0 to 1023. 1 in this variable corresponds to positive d[i] and 0 to negative d[i].
e.g. for bin(8) = 0000001000 implies that d7 will take value -d7 and rest will be positive. Repeat this for all 0 to 1023 to get all combinations.
For example, if D = [d1,d2,...d10], we will have 1024 (2^10) combinations such that:
D1 = [-d1,d2,d3,....d10]
D2 = [-d1,-d2,d3,....d10]
D3 = [d1,-d2,d3,....d10] ...
D1024 = [-d1,-d1,-d3,....-d10]
Thank You!
you can just use the builtin itertools.product to make all combinations of positive and negative values.
from itertools import product
inputs = list(range(10)) # [1,2,3,4,5,6,7,8,9]
outputs = []
choices = [(x,-x) for x in inputs]
for item in product(*choices):
outputs.append(item)
print(outputs[:3])
print(len(outputs))
# [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 7, 8, -9), (0, 1, 2, 3, 4, 5, 6, 7, -8, 9)]
# 1024
in a compressed form:
outputs = [item for item in product(*[(x,-x) for x in inputs])]

Sum values in a list one by one, check for any step if the sum is equal to 0 and store values contributing to the sum to a new list Python 3.x

I have a list like this:
my_list = [-1, 5, 6, -7, -3, 7, 9, -8, 4, -12, ....., N]
Using Python 3.x, I would like to sum numbs one by one and check at each step if the sum is equal to zero. If it is not continue, otherwise break and store values contributing to the sum (when sum = 0) in a new list.
For now, I'm not considering problems regarding performance.
Can you please help me?
Really appreciate your help!
If I understood correctly, you want to sum up your items until the sum is different from 0 and also save this numbers in another list.
You can do it like this
my_list = [-1, 5, 6, -7, -3, 7, 9, -8, 4, -12]
numbers_that_sum_zero = []
total = 0
for i in range(len(my_list)):
total += my_list[i]
numbers_that_sum_zero.append(my_list[i])
if total == 0:
break
print(numbers_that_sum_zero)
This will return
[-1, 5, 6, -7, -3]
An option using numpy:
import numpy as np
my_list = [-1, 5, 6, -7, -3, 7, 9, -8, 4, -12]
a = np.array(my_list)
result = a[:a.cumsum().tolist().index(0)+1]
# or result = a[:np.where(a.cumsum()==0)[0][0]+1]
Output:
array([-1, 5, 6, -7, -3])
This returns the first subset of number in which the sum is 0. If there's no values in the list that sums to 0 at all, it raises an error.
You can handle it to return NaN or any other output with:
try:
result = a[:a.cumsum().tolist().index(0)+1]
except:
result = np.nan

Calculate the duplicate in multidimensional numpy array

I am using python-3.x and I would like to calculate the number of duplicates in numpy array.... for example:
import numpy as np
my_array = np.array([[2, 3, 5],
[2, 3, 5], # duplicate of row 0 (this will be count as 1)
[2, 3, 5], # duplicate of row 0 (this will be count as 2)
[1, 0, 9],
[3, 6, 6],
[3, 6, 6], # duplicate of row 0 (this will be count as 3)
[1, 0, 9]])
What I would like to get from the outptu is the number of duplicates in this array:
the number of the duplicate is 3
most of the methods are returning the values such as collections.Counter or return_counts and they not returning what I want if I am using them right.
Any advice would be much appreciated
You can get the duplicate count of array by take length of array - length of unique members of array:
the_number_of the duplicate = len(my_array) - len(np.unique(my_array, axis=0))
And the result of your example is 4 ([1,0,9] is duplicate also).
Here's a slight variation from #Anh Ngoc's answer. (for older versions of numpy where axis is not supported by np.unique)
number_of_duplicates = len(my_array) - len(set(map(tuple, my_array)))

Python: Extend a 1D array in heterogeneous steps provided by the values in another 1D array

I have two equally long 1D arrays: "Number_of_Data" and "Value". With these two arrays, I would like to create a third array ("Final_Array") where each of the element values in "Value" appears as many times as specified by the corresponding element value in "Number_of_Data".
Let me give you an example:
import numpy as np
# Create the Arrays
Number_of_Data = np.asarray([2, 4, 1, 2, 3, 6, 3])
Value = np.arange(0, 7, 1)
# Then, somehow, I want Final_Array to be:
Final_Array
array([0, 0, 1, 1, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6])
Is there a python function to accomplish this? (In reality, my arrays are of course much longer than the length of "Value" and the maximum number of data is much higher than the highest value in "Number_of_Data")
I am not aware of any numpy integrated function. The easiest approach is to create a simple function that takes the two arrays and gives you back the desired vector exploiting two for loops.
import numpy as np
def final(numbers, values):
n_values = len(values)
vector = np.zeros(np.sum(numbers))
counter = 0
for k in range(n_values):
for j in range(numbers[k]):
vector[counter] = values[k]
counter += 1
return vector
Number_of_Data = np.asarray([2, 4, 1, 2, 3, 6, 3])
Value = np.arange(0, 7, 1)
Final_Array = final(Number_of_Data, Value)
print(Final_Array)
This gives back
[ 0. 0. 1. 1. 1. 1. 2. 3. 3. 4. 4. 4. 5. 5. 5. 5. 5. 5. 6. 6. 6.]

Numpy arrays: can I multiply only a few elements in the array and not all of them?

I am using Python3 and numpy with matplotlib on a project to get Jupiter's Mass from observational telescope astrometry. I want to take an array of numbers, say from 1 to 10, and multiply only a few of them in order, say 1 to 4, by -1.
So 1 to 4 is now negative and 5 to 10 is still positive. I imagine out put like this:
L = [1,2,3,4,5,6,7,8,9,10]
array_L = np.array(L)
>>>array_L
array([1,2,3,4,5,6,7,8,9,10])
neg = array_L[0:4]
>>>neg
array([1,2,3,4])
Neg = neg * -1
>>>Neg
array([-1,-2,-3,-4])
Now I need a way of combining neg and array_L into a new final array that would output like this:
# pseudo code: Neg + array_L(minus elements 0 to 4) = New_L
New_L = array([-1,-2,-3,-4, 5, 6, 7, 8, 9, 10])
Also I know it may be possible to do a limited element iteration over just the elements I want and not the whole array. I can do some of these operations on the list vs the array if it would make it easier.
You are almost there! Try this:
L = array([1,2,3,4,5,6,7,8,9,10])
L[0:4] *= -1
print(L)
Just like with regular python lists, you can do operations on slices of NumPy arrays to change them in-place:
>>> import numpy
>>> L = [1,2,3,4,5,6,7,8,9,10]
>>> array_L = numpy.array(L)
>>> array_L
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
>>> array_L[0:4] *= -1
>>> array_L
array([-1, -2, -3, -4, 5, 6, 7, 8, 9, 10])

Resources