How to represent ":" in numpy [duplicate] - python

This question already has answers here:
Array Assignment in numpy / : colon equivalent
(2 answers)
Closed 1 year ago.
I want to slice a multidimensional ndarray but don't know which dimension I will slice on. Lets say we have a ndarray A with shape (6,7,8). Sometimes I need to slice on 1st dimension A[:,3,4], sometimes on third A[1,2,:].
Is there any symbol represent the ":"? I want to use it to generate an index array.
index=np.zeros(3)
index[0]=np.:
index[1]=3
index[2]=4
A[index]

The : slice can be explicitly created by calling slice(None) Here's a short example:
import numpy as np
A = np.arange(9).reshape(3, -1)
# extract the 2nd column
A[:, 1]
# equivalently we can do
cslice = slice(None) # represents the colon
A[cslice, 1]

You want index to be a tuple, with a mix of numbers, lists and slice objects. A number of the numpy functions that take an axis parameter construct such a tuple.
A[(slice(None, None, None), 3, 4)] # == A[:, 3, 4]
there are various ways constructing that tuple:
index = (slice(None),)+(3,4)
index = [slice(None)]*3; index[1] = 3; index[2] = 4
index = np.array([slice(None)]*3]; index[1:]=[3,4]; index=tuple(index)
In this case index can be list or tuple. It just can't be an array.
Starting with a list (or array) is handy in that you can modify values, but it is best to convert it to a tuple before use. I'd have to check the docs for the details, but there are circumstances where a list means something different from a tuple.
http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
Remember that a slicing tuple can always be constructed as obj and used in the x[obj] notation. Slice objects can be used in the construction in place of the [start:stop:step] notation. For example, x[1:10:5,::-1] can also be implemented as obj = (slice(1,10,5), slice(None,None,-1)); x[obj] . This can be useful for constructing generic code that works on arrays of arbitrary dimension.

Related

How to iterate over single element of numpy array

I have a numpy array of shape (100, 1), having all elements similar to as shown below
arr[0] = array(['37107287533902102798797998220837590246510135740250'], dtype=object)
I need to iterate over this single element of array and get the last 10 elements of it. I have not been able to find out how to iterate over single element.
I tried arr[0][-10:] but it returned the entire element and not the last 10 elements
You can get what you want by list comprehension.
np.array([item[0][-10:] for item in arr])
If arr.shape is (100,1), then arr[0].shape is (1,), which is shown array(['astring']) brackets.
arr[0,0] should be a string, e.g. '37107287533902102798797998220837590246510135740250'
Strings take slice indexing, eg. arr[0,0][-10:]
arr[0][0] also works to get one string, but the [0,0] syntax is better.
It isn't clear at what level you want to iterate, since just getting the last 10 characters of one of the string elements doesn't need iteration.
Anyways, pay attention to what each level of indexing is producing, whether it be another array, a list, or a string. Indexing rules for these different classes are similar, but different in important ways.
# import numpy
import numpy as np
arr = np.array(['37107287533902102798797998220837590246510135740250'], dtype=object)
# print the last 10 elements of the array
print(arr[0][-10:])
# iterate through the array and print the elements in reverse order
for i in arr[0][::-1]:
print(i)
# iterate through the array and print the last 10 elements in reverse order
for i in arr[0][-10:][::-1]:
print(I)
# iterate through the array and print the last 10 elements in forward order
for i in arr[0][-10:]:
print(i)
#hpaulj makes a good point. My original answer works with numpy as requested but I didn't really leave the OP an explanation. Using his string advice this how I would do it if it was a string and I wanted to iterate for some reason:
s1 = '37107287533902102798797998220837590246510135740250'
result = 0
for x in s1[-10:]:
print(x)
result += int(x)
print(result)

What is `a[start:stop, i]` in Python slicing? [duplicate]

This question already has answers here:
What does a colon and comma stand in a python list?
(4 answers)
Closed 1 year ago.
Python doc for built-in function slice is (emphasis mine):
class slice(stop)
class slice(start, stop[, step])
Return a slice object representing the set of indices specified by range(start, stop, step). The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default). They have no other explicit functionality; however they are used by NumPy and other third party packages. Slice objects are also generated when extended indexing syntax is used. For example: a[start:stop:step] or a[start:stop, i]. See itertools.islice() for an alternate version that returns an iterator.
What does a[start:stop, i] mean?
I tried it out (in Python 3.6):
a = [1, 2, 3, 4, 5, 6]
a[1:3,1]
but got:
TypeError: list indices must be integers or slices, not tuple
You cannot combine : and , with lists.
: is for direct slicing:
a[1:3:1]
, is used with slice:
a[slice(1,3,1)]
However with objects supporting it (like numpy arrays) you can slice in several dimensions:
import numpy as np
a = np.array([[0,1,3],[3,4,5]])
a[0:1,2]
output: array([3])

Replacing the ith element of a list with a slice object

This is a very simple question but I cannot find documentation anywhere for it. I would like to change the ith element of a list to a slice ("literal colon", like in [:]). Is there any way of doing this?
I have tried doing this:
indexlist = [0] * dim
indexlist[i] = :
This throws a syntax error but I think it gets the point across of what I would like to do.
By a "literal colon" you seem to mean a slice object.
For example:
your_list[i] = slice(None)
To explain what's going on, slicing expressions are actually passed around as tuples of slice objects (or ints, etc).
something[start:stop:step] is equivalent to something[slice(start, stop, step)]. Similarly, something[:] is equivalent to something[slice(None)].
Slicing is implemented through an object's __getitem__ method, so this is also equivalent to something.__getitem__(slice(start, stop, step))
Because you mention numpy in the comments, you might have a look at np.index_exp or np.s_. It lets you quickly create tuples of slices from indexing, and allows you to see what happens.
For example:
import numpy as np
print np.s_[:, 1:5, ::-1, ...]
yields:
(slice(None, None, None), slice(1, 5, None), slice(None, None, -1), Ellipsis)
Which is a tuple of slice objects that you can store and then directly use to slice an object. (e.g. slices = np.s_[0, :, :] and then y = x[slices]).

Indexing and slicing structured ndarrays

Now I'm trying to understand possible ways to index numpy structured arrays, and I kinda get stuck with it. Just a couple of simple examples:
import numpy as np
arr = np.array(zip(range(5), range(5, 10)), dtype=[('a', int), ('b', int)])
arr[0] # first row (record)
arr[(0,)] # the same, as expected
arr['a'] # field 'a' of each record
arr[('a',)] # "IndexError: unsupported iterator index" ?!
arr[1:3] # second and third rows (records)
arr[1:3, 'a'] # "ValueError: invalid literal for long() with base 10: 'a'" ?!
arr['a', 1:3] # same error
arr[..., 'a'] # here too...
arr['a', ...] # and here
So, two subquestions arise:
Why is the result for a plain value ('a' in this case) different from the corresponding singleton tuple (('a',))?
Why the last four lines raise the error? And, probably more important, how to get the slice arr['a'][1:3] with a single slice? As you can see, obvious arr['a', 1:3] doesn't work.
I also observed the indexing behavior for built-in list and non-structured ndarray, but couldn't find such issues there: putting a single value in a tuple doesn't change anything, and of course indexing like arr[1, 1:3] for plain ndarray works as expected. Given that, should the errors in my example be considered as bugs in numpy?
First, fields are not the same thing as dimensions - although your array arr has two fields and five rows, numpy actually treats it as one-dimensional (it has shape (5,)). Second, tuples have a special status when used as indices into numpy arrays. When you put a tuple inside the square indexing brackets, numpy interprets it as a sequence of indices into the corresponding dimensions of the array. In the special case where you have nested tuples, each inner tuple is treated as a sequence of indices into that dimension (as if it were a list).
Since fields don't count as dimensions, when you index it with arr[('a',)], numpy interprets 'a' as an index into the rows of arr. The IndexError is therefore raised because strings aren't a valid type for indexing into a dimension of an array (what is the 'a'th row?).
The same thing happens when you try arr['a', 1:3], because this is equivalent to indexing with the tuple ('a', slice(1, 3, None)). The comma between 'a' and 1:3 is what makes it a tuple, regardless of the lack of brackets. Again, numpy tries to index into the rows of arr with 'a', which is invalid. However, even if both elements were valid index types, you would still get an IndexError, since the length of your tuple (2) is greater than the number of dimensions in arr (1).
arr['a'][1:3] and arr[1:3]['a'] are both perfectly valid ways to index a slice of a field.

Counting array elements in Python [duplicate]

This question already has answers here:
How do I get the number of elements in a list (length of a list) in Python?
(11 answers)
Closed 5 years ago.
How can I count the number of elements in an array, because contrary to logic array.count(string) does not count all the elements in the array, it just searches for the number of occurrences of string.
The method len() returns the number of elements in the list.
Syntax:
len(myArray)
Eg:
myArray = [1, 2, 3]
len(myArray)
Output:
3
len is a built-in function that calls the given container object's __len__ member function to get the number of elements in the object.
Functions encased with double underscores are usually "special methods" implementing one of the standard interfaces in Python (container, number, etc). Special methods are used via syntactic sugar (object creation, container indexing and slicing, attribute access, built-in functions, etc.).
Using obj.__len__() wouldn't be the correct way of using the special method, but I don't see why the others were modded down so much.
If you have a multi-dimensional array, len() might not give you the value you are looking for. For instance:
import numpy as np
a = np.arange(10).reshape(2, 5)
print len(a) == 2
This code block will return true, telling you the size of the array is 2. However, there are in fact 10 elements in this 2D array. In the case of multi-dimensional arrays, len() gives you the length of the first dimension of the array i.e.
import numpy as np
len(a) == np.shape(a)[0]
To get the number of elements in a multi-dimensional array of arbitrary shape:
import numpy as np
size = 1
for dim in np.shape(a): size *= dim
Or,
myArray.__len__()
if you want to be oopy; "len(myArray)" is a lot easier to type! :)
Before I saw this, I thought to myself, "I need to make a way to do this!"
for tempVar in arrayName: tempVar+=1
And then I thought, "There must be a simpler way to do this." and I was right.
len(arrayName)

Categories

Resources