Everytime I run this code it says that numpy.ndarray has not attribute 'index' - python-3.x

When I run this code it returns that the numpy.ndarray object has no attributes. I'm trying to write a function that in case the number given is in the array will return with the position of that number in the array.
a = np.c_[np.array([1, 2, 3, 4, 5])]
x = int(input('Type a number'))
def findelement(x, a):
if x in a:
print (a.index(x))
else:
print (-1)
print(findelement(x, a))

Please use np.where instead of list.index.
import numpy as np
a = np.c_[np.array([1, 2, 3, 4, 5])]
x = int(input('Type a number: '))
def findelement(x, a):
if x in a:
print(np.where(a == x)[0][0])
else:
print(-1)
print(findelement(x, a))
Result:
Type a number: 3
2
None
Note np.where returns the indices of elements in an input array where
the given condition is satisfied.

You should check out np.where and np.argwhere.

Related

Find the index location of an element in a Numpy array

If I have:
x = np.array(([1,4], [2,5], [2,6], [3,4], [3,6], [3,7], [4,3], [4,5], [5,2]))
for item in range(3):
choice = random.choice(x)
How can I get the index number of the random choice taken from the array?
I tried:
indexNum = np.where(x == choice)
print(indexNum[0])
But it didn't work.
I want the output, for example, to be something like:
chosenIndices = [1 5 8]
Another possibility is using np.where and np.intersect1d. Here random choice without repetition.
x = np.array(([1,4], [2,5], [2,6], [3,4], [3,6], [3,7], [4,3], [4,5], [5,2]))
res=[]
cont = 0
while cont<3:
choice = random.choice(x)
ind = np.intersect1d(np.where(choice[0]==x[:,0]),np.where(choice[1]==x[:,1]))[0]
if ind not in res:
res.append(ind)
cont+=1
print (res)
# Output [8, 1, 5]
You can achieve this by converting the numpy array to list of tuples and then apply the index function.
This would work:
import random
import numpy as np
chosenIndices = []
x = np.array(([1,4], [2,5], [2,6], [3,4], [3,6], [3,7], [4,3], [4,5], [5,2]))
x = x.T
x = list(zip(x[0],x[1]))
item = 0
while len(chosenIndices)!=3:
choice = random.choice(x)
indexNum = x.index(choice)
if indexNum in chosenIndices: # if index already exist, then it will rerun that particular iteration again.
item-=1
else:
chosenIndices.append(indexNum)
print(chosenIndices) # Thus all different results.
Output:
[1, 3, 2]

Numpy: Size of a 2D array matrix?

How do my 2 statements bellow differ in internal mechanism, while they are however giving the same output?
x = np.array([[**1, 2, 3, 6, 7, 8**], [**4, 5, 6, 8, 9, 5**]])
np.size(x)
x.size
Both are correct outputs as the size of the array is 12.
Internally np.size(x) calls x.size when axis is not specified sp in this case the result is the same.
if axis is None:
try:
return a.size
except AttributeError:
return asarray(a).size
However, if you specify the axis, then the result would be different.
>>> a=np.arange(16).reshape(4,4)
>>> a.shape
(4, 4)
>>> np.size(a,axis=1)
4
>>> a.size
16
np.size accepts parameter axis; x.size always returns the total number of elements:
def size(a, axis=None):
"""
Return the number of elements along a given axis.
Parameters
----------
a : array_like
Input data.
axis : int, optional
Axis along which the elements are counted. By default, give
the total number of elements.
Returns
-------
element_count : int
Number of elements along the specified axis.
See Also
--------
shape : dimensions of array
ndarray.shape : dimensions of array
ndarray.size : number of elements in array
Examples
--------
>>> a = np.array([[1,2,3],[4,5,6]])
>>> np.size(a)
6
>>> np.size(a,1)
3
>>> np.size(a,0)
2
"""
if axis is None:
try:
return a.size
except AttributeError:
return asarray(a).size
else:
try:
return a.shape[axis]
except AttributeError:
return asarray(a).shape[axis]

Generate a list with two unique elements with specific length [duplicate]

Simple question here:
I'm trying to get an array that alternates values (1, -1, 1, -1.....) for a given length. np.repeat just gives me (1, 1, 1, 1,-1, -1,-1, -1). Thoughts?
I like #Benjamin's solution. An alternative though is:
import numpy as np
a = np.empty((15,))
a[::2] = 1
a[1::2] = -1
This also allows for odd-length lists.
EDIT: Also just to note speeds, for a array of 10000 elements
import numpy as np
from timeit import Timer
if __name__ == '__main__':
setupstr="""
import numpy as np
N = 10000
"""
method1="""
a = np.empty((N,),int)
a[::2] = 1
a[1::2] = -1
"""
method2="""
a = np.tile([1,-1],N)
"""
method3="""
a = np.array([1,-1]*N)
"""
method4="""
a = np.array(list(itertools.islice(itertools.cycle((1,-1)), N)))
"""
nl = 1000
t1 = Timer(method1, setupstr).timeit(nl)
t2 = Timer(method2, setupstr).timeit(nl)
t3 = Timer(method3, setupstr).timeit(nl)
t4 = Timer(method4, setupstr).timeit(nl)
print 'method1', t1
print 'method2', t2
print 'method3', t3
print 'method4', t4
Results in timings of:
method1 0.0130500793457
method2 0.114426136017
method3 4.30518102646
method4 2.84446692467
If N = 100, things start to even out but starting with the empty numpy arrays is still significantly faster (nl changed to 10000)
method1 0.05735206604
method2 0.323992013931
method3 0.556654930115
method4 0.46702003479
Numpy arrays are special awesome objects and should not be treated like python lists.
use resize():
In [38]: np.resize([1,-1], 10) # 10 is the length of result array
Out[38]: array([ 1, -1, 1, -1, 1, -1, 1, -1, 1, -1])
it can produce odd-length array:
In [39]: np.resize([1,-1], 11)
Out[39]: array([ 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1])
Use numpy.tile!
import numpy
a = numpy.tile([1,-1], 15)
use multiplication:
[1,-1] * n
If you want a memory efficient solution, try this:
def alternator(n):
for i in xrange(n):
if i % 2 == 0:
yield 1
else:
yield -1
Then you can iterate over the answers like so:
for i in alternator(n):
# do something with i
Maybe you're looking for itertools.cycle?
list_ = (1,-1,2,-2) # ,3,-3, ...
for n, item in enumerate(itertools.cycle(list_)):
if n==30:
break
print item
I'll just throw these out there because they could be more useful in some circumstances.
If you just want to alternate between positive and negative:
[(-1)**i for i in range(n)]
or for a more general solution
nums = [1, -1, 2]
[nums[i % len(nums)] for i in range(n)]

Find elements in list which occure only one time in list

I have written a function which return a list of elements which occur only once in a given list and it is working as expected but this is not what I want is there any built-in function or other method which do same functionalities without iterating:
def unique_items(ls):
return [item for item in ls if ls.count(item)==1]
print(unique_items([1,1,1,2,3,2,4,5,4]))
>>> from collections import Counter
>>> a = [1,2,3,4,5,1,2]
>>> c = Counter(a)
>>> c
Counter({1: 2, 2: 2, 3: 1, 4: 1, 5: 1})
>>> [k for k, v in c.items() if v == 1]
[3, 4, 5]
If you don't want to use an explicit loop, you can use filter:
def unique_items(ls):
return list(filter(lambda s : ls.count(s) == 1, ls))
print(unique_items([1,1,1,2,3,2,4,5,4]))
Output:
[3, 5]
Comparing some options mentioned here:
def func_1(ls):
return [
item
for item in ls
if ls.count(item) == 1]
def func_2(ls):
c = collections.Counter(ls)
return [
k
for k, v in c.items()
if v == 1]
Comparisson code:
import timeit
a_1 = [1,1,1,2,3,2,4,5,4]
a_2 = [1,1,1,2,3,2,4,5,4] * 100
for f in [func_1, func_2]:
print(f.__name__)
print(
'short list',
timeit.timeit(
'f(a)',
'from __main__ import {} as f, a_1 as a'.format(f.__name__),
number=100))
print(
'long list ',
timeit.timeit(
'f(a)',
'from __main__ import {} as f, a_2 as a'.format(f.__name__),
number=100))
Results:
func_1
short list 0.00014933500006009126
long list 0.5417057829999976
func_2
short list 0.0005539439998756279
long list 0.0029211379996922915
So far, func_2 is faster for large inputs and func_1 is slightly faster for very short inputs.

Fastest way to find all the indexes of maximum value in a list - Python

I am having list which as follows
input_list= [2, 3, 5, 2, 5, 1, 5]
I want to get all the indexes of maximum value. Need efficient solution. The output will be as follows.
output = [2,4,6] (The above list 5 is maximum value in a list)
I have tried by using below code
m = max(input_list)
output = [i for i, j in enumerate(a) if j == m]
I need to find any other optimum solution.
from collections import defaultdict
dic=defaultdict(list)
input_list=[]
for i in range(len(input_list)):
dic[input_list[i]]+=[i]
max_value = max(input_list)
Sol = dic[max_value]
You can use numpy (numpy arrays are very fast):
import numpy as np
input_list= np.array([2, 3, 5, 2, 5, 1, 5])
i, = np.where(input_list == np.max(input_list))
print(i)
Output:
[2 4 6]
Here's the approach which is described in comments. Even if you use some library, fundamentally you need to traverse at least once to solve this problem (considering input list is unsorted). So even lower bound for the algorithm would be Omega(size_of_list). If list is sorted we can leverage binary_search to solve the problem.
def max_indexes(l):
try:
assert l != []
max_element = l[0]
indexes = [0]
for index, element in enumerate(l[1:]):
if element > max_element:
max_element = element
indexes = [index + 1]
elif element == max_element:
indexes.append(index + 1)
return indexes
except AssertionError:
print ('input_list in empty')
Use a for loop for O(n) and iterating just once over the list resolution:
from itertools import islice
input_list= [2, 3, 5, 2, 5, 1, 5]
def max_indexes(l):
max_item = input_list[0]
indexes = [0]
for i, item in enumerate(islice(l, 1, None), 1):
if item < max_item:
continue
elif item > max_item:
max_item = item
indexes = [i]
elif item == max_item:
indexes.append(i)
return indexes
Here you have the live example
Think of it in this way, unless you iterate through the whole list once, which is O(n), n being the length of the list, you won't be able to compare the maximum with all values in the list, so the best you can do is O(n), which you already seems to be doing in your example.
So I am not sure you can do it faster than O(n) with the list approach.

Resources