How to index two elements from a Python list? - python

How come I can't index a Python list for multiple out-of-sequence index positions?
mylist = ['apple','guitar','shirt']
It's easy enough to get one element, but not more than one.
mylist[0] returns 'apple', but mylist[0,2] returns TypeError: list indices must be integers or slices, not tuple
So far, only this seems to work which looks hectic:
np.asarray(mylist)[[0,2]].tolist()

Use Extended Slices:
mylist = ['apple','guitar','shirt']
print(mylist[::2])
#Output: ['apple', 'shirt']

Use list comprehension:
print([mylist[i] for i in [0, 2]])
# ['apple', 'shirt']
Or use numpy.array:
import numpy as np
print(np.array(mylist)[[0, 2]])
# ['apple', 'shirt']

Python list supports only integer and slice for indices. The standard slicing rule of python is as follow:
i:j:k inside the square bracket for accessing more than one element.
where i is the starting index, j is the ending index and k is the steps.
>>> list_ = ['apple','guitar','shirt']
>>> mylist[0:2]
['apple', 'guitar']
if you want some random element as per some certain indices then use List Comprehension or just a for loop
There is an another way for accessing items from certain indices by using map() function.
>>> a_list = [1, 2, 3]
>>> indices_to_access = [0, 2]
>>> accessed_mapping = map(a_list.__getitem__, indices_to_access)
>>> accessed_list = list(accessed_mapping)
>>> accessed_list
[ 1, 3]

A recommendation from me would be: use the NumPy library (import numpy as np). It will allow you to create a numpy array which has advantages over a standard list. Using the numpy array, you will be able to access as many items as you would like through a process called Fancy Indexing.
mylist[0] returns 'apple'
The above code/statement which was available in the question description depicts a Python programmer performing indexing- which is the process of passing the index position of a sinlge item in order to retrieve the item- However in the event of requiring multiple items, that would be difficult/not possible.
import numpy as np #import the numpy package
mylist = np.array(['apple','guitar','shirt']) #create the numpy array
mylist[[0,2]] #return the first and third items ONLY. (zero-indexed)
Out[11]: array(['apple', 'shirt'], dtype='<U6')
If you were to make use of the NumPy library in python (looking above), you would be able to create a NumPy array, which allows for more methods and operations to be performed on your array.
As compared to mylist[0] which returns a single/individual item only, Using mylist[[0,2]] we specify to the python compiler that we wish to retrieve exactly two elements from our list, and those elements are located at index positions '0' and '2'. (zero-indexed). Notice that we passed in the index positions of the desired elements in a list. Therefore instead of returning one element, we return two (or as many as you would like).

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)

how to apply function to a list element within a list of lists?

I have a list of lists. Here is an example of 2 of the lists inside a list:
global_tp_old = [[2, 1, 0.8333595991134644],[2, 1, 0.8530714511871338]]
I want to access a dataframe index where the index is specified in the first element of the above list in a list. At the moment I have tried:
global_tp_new = []
for element in global_tp_old:
element[:][0] = df_unique[element[:][0]]
global_tp_new.append(element)
where df_unique is a pandas dataframe produced like this:
['img1.png', 'img2.png', 'img3.png']
I'm trying to match the first element from the list defined above to the number in df_unique.
I should get:
'img3.png'
as it's the 3rd element (0 indexing)
However, I get the incorrect output where it essentially returns the first element every time. It's probably obvious but what do I do to fix this?
Remember that your element array is actually a reference into the original list. If you modify the list, you'll modify global_tp_old as well.
Something like this, although you may need to change the dataframe indexing depending on whether you're looking for rows or columns.
global_tp_old = [[2, 1, 0.8333595991134644],[2, 1, 0.8530714511871338]]
global_tp_new = []
for element in global_tp_old:
element = [df_unique.iloc[element[0]]] + element[1:]
global_tp_new.append(element)
List comprehension might be useful to apply a function fun to the first element of each list in a list of lists (LoL).
LoL = [[61, 1, 0.8333595991134644],[44, 1, 0.8530714511871338]]
newL = [fun(l_loc[0]) for l_loc in LoL]
No need to use a Pandas DataFrame.

How to change string elements in a list from strings to numpy array names?

I have a python list, like so:
list = [('array_1','array_2'),('array_1','array_3'),('array_2','array_3')]
The pairs in the list above are actually named numpy arrays, so I want to remove the quotes around each array name so that I'm left with:
list = [(array_1, array_2), (array_1, array_3), (array_2, array_3)]
How do I go about doing this?
Now you lst will contain actual NumPy arrays instead of just strings.
lst = [("array_1", "array_2"), ("array_1", "array_3"), ("array_2", "array_3")]
lst = [(globals()[i], globals()[j]) for i, j in lst]
This will output the numpy array (like array_1):
# str will be like : 'array_1'
globals()[str]
or
eval(str)
Note :
But I recommend to create a dictionary with keys as the strings and values as the corresponding arrays instead of eval and globals()
like this:
dict_ = {'array_1': array_1, 'array_2': array_2, 'array_3': array_3}
And use this dictionary wherever you want to access the variable

how to efficiently link lines of numpy array to sets of tags?

I am trying to convert a list of data structure, all of the same type, into a numpy arrays. It works well for all the number attributes but there is one attribute whose value is a set of tags (strings). And I don't see how to model that properly with numpy .
So far, I use a 2d array. Each row contains the attributes of one data structure, one per columns. But for the set of strings, I don't know how to use that in a numpy array.
It seems that I can put a set as the value for a cell in the array but It seems to break the point of numpy : fixed size arrays with efficient functions that apply on them.
Any idea ?
I think the best alternative is to use a list of tuples
Supposing l is your list:
In [1]: l = [[4,5,6,'a','b'],['x','y',2,3]]
In [2]: _l = [tuple(elem) for elem in l]
In [3]: _l
Out[1]: [(4, 5, 6, 'a', 'b'), ('x', 'y', 2, 3)]
Alternatively you could create a list of tuple where the first element of the tuple is the numpy array, and the second element is the tag.

Convert array to python scalar

I need big help, please check out this code:
import.math
dose =20.0
a = [[[2,3,4],[5,8,9],[12,56,32]]
[[25,36,45][21,65,987][21,58,89]]
[[78,21,98],[54,36,78],[23,12,36]]]
PAC = math.exp(-dose*a)
this what I would like to do. However the error I am getting is
TypeError: only length-1 arrays can be converted to Python scalars
If you want to perform mathematical operations on arrays (whatever their dimensions...), you should really consider using NumPy which is designed just for that. In your case, the corresponding NumPy command would be:
PAC = numpy.exp(-dose*np.array(a))
If NumPy is not an option, you'll have to loop on each element of a, compute your math.exp, store the result in a list... Really cumbersome and inefficient. That's because the math functions require a scalar as input (as the exception told you), when you're passing a list (of lists). You can combine all the loops in a single list comprehension, though:
PAC = [[[math.exp(-dose*j) for j in elem] for elem in row] for row in a]
but once again, I would strongly recommend NumPy.
You should really use NumPy for that.
And here is how you should do it using nested loops:
>>> for item in a:
... for sub in item:
... for idx, number in enumerate(sub):
... print number, math.exp(-dose*number)
... sub[idx] = math.exp(-dose*number)
Using append is slow, because every time you copy the previous array and stack the new item to it.
Using enumerate, changes numbers in place. If you want to keep a copy of a, do:
acopy = a[:]
If you don't have much numbers, and NumPy is an over kill, the above could be done a tiny bit faster using list comprehensions.
If you want, for each element of the array to have it multiplied by -dose then apply math.exp on the result, you need a loop :
new_a = []
for subarray in a:
new_sub_array = []
for element in sub_array:
new_element = math.exp(-dose*element)
new_sub_array.append(new_element)
new_a.append(new_sub_array)
Alternatvely, if you have a mathlab background, you could inquire numpy, that enable transformations on array.

Categories

Resources