python single element tuple - python

Suppose I have a matrix M and an indexing set idx=[(0,1),(2,3),(3,2)] and I want to create two sets of tuples, idx_leq1 consisting of those tuples whose first and second elements are both less than or equal to 1 and idx_geq2 consisting of those tuples whose first and second elements are both greater than or equal to 2.
I want to access the elements M[idx_leq1] and M[idx_geq2] cleanly. I have tried idx_leq1 = tuple([e for e in idx if e[0]<=1 and e[1]<=1]), but this returns idx_leq1 = ((0,1),) which I can't use to index M. On the other hand, idx_geq2 = tuple([e for e in idx if e[0]>=2 and e[1]>=2]) = ((2,3),(3,2)) works.
How can I solve this for the case where my first index set consists of only one coordinate pair? I don't want to do M[idx_leq1[0]].
I can do: list(chain(*[(e,) for e in idx if e[0]<=1 and e[1]<=1])) and list(chain(*[(e,) for e in idx if e[0]>=2 and e[1]>=2])), but then I still have to grab the first element for idx_leq1 whereas I can pass idx_geq2 to M and grab the appropriate elements.
Thanks!

[Tested with numpy.mat]
[M[0, 1]] should be fetched as in M[[0], [1]]. When indexing matrix, Multidimensional list-of-locations indexing requires k lists of index each working with one dimension.
For example, in order to fetch M[0, 3], M[1, 4], M[2, 5], one should use M[[0, 1, 2], [3, 4, 5]]. In other word, the index that you give to M should not be considered lists of coordinates. Rather, they are lists of "coordinates on each dimension".
In your case, a M[[0, 1]] (or its equivalent in tuple type) fetches M[0], M[1] as [0, 1] is considered to work on the first dimension, and the second dimension is broadcasted.
Ref: http://scipy-cookbook.readthedocs.io/items/Indexing.html#Multidimensional-list-of-locations-indexing
This reference believes that the reason to use "list of dims" rather than "list of coordinates" is to save number of instances, as unpacking many tuples might be expensive.

Related

Get indices of top N values from list in the order of the values

I have a list like a=[3,5,7,12,4,1,5] and need to get the indices of the top K(=3) elements of this list, in the order of the elements. So in this case, result should be
[3,2,1]
since top 3 elements are 12, 7, 5 (last one is tie so first index is returned).
What is the simplest way to get this?
As this is tagged numpy, you can use numpy.argsort on the opposite values (for reverse sorting), then slice to get the K desired values:
a = np.array([3,5,7,12,4,18,1,5,18])
K = 3
out = np.argsort(-a)[:K]
output: array([3, 2, 1])
If you want the indices in order of the original array but not necessarily sorted themselves in order of the values, you can also use numpy.argpartition:
out = np.argpartition(a, K)[-K:]
I assume you mean 3,2,1 right?
[a.index(i) for i in sorted(a)[:3:-1]]
Personally, I would create a sorted list through the sorted method, then compare the first K values with the .index attribute of a. This will yield you your desired result.
K = 3 #Number of elemens
a = [3,5,7,12,4,1,5]
a_sorted = sorted(a,reverse=True)
b = [a.index(v) for v in a_sorted[:K]]
print(b)
>>> [3, 2, 1]

How do you use the contents of a list literally, rather than using it as a 'list'? ; TypeError: list indices must be integers or slices, not list [duplicate]

I want to make a function in python which receives as arguments a matrix, a coordinate for the line and another coordinate for the column. For example: A matrix m=[[1,2,3], [4,5,6]] and the function will receive the arguments (m,0,0)
It should return 1 (Which is the number located in position 0,0 in the matrix).
Think of it as a list of lists rather than a "matrix", and the logic becomes more obvious. Matrix m has two elements: m[0] = [1, 2, 3] and m[1] = [4, 5, 6]. So accessing a single value from within those lists requires another index. For example, m[0][1] = 2.
def matrix(m, a, b):
return m[a][b] # element b from list a in list m
If you really want to use a matrix, consider numpy.

Assign the new value to a tensor at specific indices

This is a simple example.
Assume that I have an input tensor M. Now I have a tensor of indices of M with size 2 x 3 such as [[0, 1], [2,2], [0,1]] and a new array of values which is corresponding with the index tensor is [1, 2, 3]. I want to assign these values to the input M satisfying that the value is assigned to the element of M at index [0,1] will be the min value (1 in this example).
It means M[0,1] = 1 and M[2,2] = 2.
Can I do that by using some available functions in Pytorch without a loop?
It can be done without loops, but I am generally not sure whether it is such a great idea, due to significantly increased runtime.
The basic idea is relatively simple: Since tensor assignments always assign the last element, it is sufficient to sort your tuples in M in descending order, according to the respective values stored in the value list (let's call it v).
To do this in pytorch, let us consider the following example:
import torch as t
X = t.randn([3, 3]) # Random matrix of size 3x3
v = t.tensor([1, 2, 3])
M = t.tensor([[0, 2, 0],
[1, 2, 1]]) # accessing the elements described above
# Showcase pytorch's result with "naive" tensor assignment:
X[tuple(M)] = v # This would assign the value 3 to position (0, 1)
# To correct behavior, sort v in decreasing order.
v_desc = v.sort(decreasing=True)
# v now contains both the values and the indices of original position
print(v_desc)
# torch.return_types.sort(
# values=tensor([3, 2, 1]),
# indices=tensor([2, 1, 0]))
# Access M in the correct order:
M_desc = M[:, v_desc.indices]
# Finally assign correct order:
X[tuple(M_desc)] = v_desc
Again, this is relatively complicated, because it involves sorting the values, and "re-shuffling" of the tensors. You can surely save at least some memory if you perform operations in-place, which is something I disregarded for the sake of legibility.
As an answer whether this can also be achieved without sorting, I am fairly certain that the answer will be "no"; tensor assignments could only be done on fairly simple conditionals, but not something more complicated like your inter-dependent conditionals would require.

What purpose does [0] serve in numpy.where(y_euler<0.0)[0]

Also what is the difference between this:
idx_negative_euler = numpy.where(y_euler<0.0)[0]
and this:
idx_negative_euler = numpy.where(y_euler<0.0)[0][0]
I realize that this returns an array of indices where the array y_euler is negative, however I simply can't figure out what the [0] or the [0][0] at the end of the line is supposed to do.
I couldn't find any documentation regarding this (I'm not even sure what to search for). I've already looked into the numpy.where documentation but that didn't help.
[0] means "get the first item of the sequence." For example if you had this list:
x = [5, 7, 9]
Then x[0] would be the first item of that sequence: 5.
numpy.where() returns a sequence. Putting [0] on the end of that expression gets the first item in that sequence.
[0][0] means "get the first item in the sequence (which is itself also a sequence), and then get the first item in that sequence". So if numpy.where() returned a list of lists, [0][0] would get the first item in the first list.
Make a simple 1d array:
In [60]: x=np.array([0,1,-1,2,-1,0])
Where returns a tuple (...,) of arrays, one for each dimension:
In [61]: np.where(x<0)
Out[61]: (array([2, 4], dtype=int32),)
pull the first (here only) element from the tuple
In [62]: np.where(x<0)[0]
Out[62]: array([2, 4], dtype=int32)
get the first element of the indexing array
In [63]: np.where(x<0)[0][0]
Out[63]: 2
the whole tuple returned by where can be used to index the array.
In [64]: x[np.where(x<0)]
Out[64]: array([-1, -1])
x[2,4], x[([2,4],)] do the same indexing.
The usefulness of the tuple value becomes more obvious when working on a 2d or higher dim array. In that case np.where(...)[0] would give the 'rows' index array. But the where(...)[0] is most common in the 1d case where the tuple layer usually isn't needed.

How to get the first element of a complex list in Python

In Python, I used to get first element of a 2-d list by
a = [[0, 1], [2, 3]]
a[:][0]
# [0, 2]
Now, the list is sort of complex, the way to get the first elements does not work
a = [['sad', 1], ['dsads', 2]]
a[:][0]
# ['sad', 1]
I do not know what is the difference here. And how to get the first elements in this simple way, rather than
[e[0] for e in a]
you could use in-built zip :
aggregates elements from each of the iterables
a = [['sad', 1], ['dsads', 2]]
zip(*a)[0]
#results :
('sad', 'dsads')
You can convert the final result to list from tuple if necessary.
* is used to flatten the list into its elements - zip accepts iterables as positional arguments. zip is sort of matrix transposition.
As commented, your first solution (a[:][0]) is not correct, it simply takes the first element of the list. Here you need to first transform the list such that each first elements are grouped into separate list, and so on for second, third .. elements. Then take the first element.
Update:
From #Rawing's comment:
If the list is very large, consider using
next(itertools.izip(*a))
This is the iterator version - this takes the list element only as necessary. In this case, it constructs each elment of the result one at a time, since we need the first element, we use next a single time to get the next (thus, first here) element of the iterator.
Using numpy :
>>> a = [['sad', 1], ['dsads', 2]]
>>> import numpy
>>> my_array = numpy.array(a)
>>> print my_array[:,0]
['sad' 'dsads']

Categories

Resources