Using the reduce function on a multidimensional array - python

So i have a particular array, that has 2 seperate arrays withing itself. What I am looking to do is to average together those 2 seperate arrays, so for instance, if i have my original array such as [(2,3,4),(4,5,6)] and I want an output array like [3,5], how would i do this? My attempt to do this is as follows:
averages = reduce(sum(array)/len(array), [array])

>>> map(lambda x: sum(x)/len(x), [(2,3,4),(4,5,6)])
[3, 5]

reduce is not a good choice here. Just use a list comprehension:
>>> a = [(2,3,4),(4,5,6)]
>>> [sum(t)/len(t) for t in a]
[3, 5]
Note that / is integer division by default in python2.
If you have numpy available, you have a nicer option:
>>> import numpy as np
>>> a = np.array(a)
>>> a.mean(axis=1)
array([ 3., 5.])

You can do this with a list comphrehesion:
data = [(2,3,4),(4,5,6)]
averages = [ sum(tup)/len(tup) for tup in data ]

Related

Calculation on list of numpy array

I'm trying to do some calculation (mean, sum, etc.) on a list containing numpy arrays.
For example:
list = [array([2, 3, 4]),array([4, 4, 4]),array([6, 5, 4])]
How can retrieve the mean (for example) ?
In a list like [4,4,4] or a numpy array like array([4,4,4]) ?
Thanks in advance for your help!
EDIT : Sorry, I didn't explain properly what I was aiming to do : I would like to get the mean of i-th index of the arrays. For example, for index 0 :
(2+4+6)/3 = 4
I don't want this :
(2+3+4)/3 = 3
Therefore the end result will be
[4,4,4] / and not [3,4,5]
If L were a list of scalars then calculating the mean could be done using the straight forward expression:
sum(L) / len(L)
Luckily, this works unchanged on lists of arrays:
L = [np.array([2, 3, 4]), np.array([4, 4, 4]), np.array([6, 5, 4])]
sum(L) / len(L)
# array([4., 4., 4.])
For this example this happens to be quitea bit faster than the numpy function
np.mean
timeit(lambda: np.mean(L, axis=0))
# 13.708808058872819
timeit(lambda: sum(L) / len(L))
# 3.4780975924804807
You can use a for loop and iterate through the elements of your array, if your list is not too big:
mean = []
for i in range(len(list)):
mean.append(np.mean(list[i]))
Given a 1d array a, np.mean(a) should do the trick.
If you have a 2d array and want the means for each one separately, specify np.mean(a, axis=1).
There are equivalent functions for np.sum, etc.
https://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html
https://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html
You can use map
import numpy as np
my_list = [np.array([2, 3, 4]),np.array([4, 4, 4]),np.array([6, 5, 4])]
np.mean(my_list,axis=0) #[4,4,4]
Note: Do not name your variable as list as it will shadow the built-ins

How do you find the largest/smallest number amongst several array's?

I'm trying to get the largest/smallest number returned out of two or more numpy.array of equal length. Since max()/min() function doesn't work on multiple arrays, this is some of the best(worst) I've come up with:
max(max(a1), max(a2), max(a3), ...) / min(min(a1), min(a2), min(a3), ...)
Alternately one can use numpy's maximum, but those only work for two arrays at time.
Thanks in advance
this is linear time and works with Numpy arrays
>>> import itertools
>>> max(itertools.chain([1,2,3],[1,2,4],[-1, -2, 5])
5
max()/min() function doesn't work on multiple arrays
map will work on an array of arrays, then return a single array, which you can then find the max or min of that array.
>>> l1 = [1,2,3]
>>> l2 = [3,4,1]
>>> l3 = [6,1,8]
>>> map(max, [l1, l2, l3])
[3, 4, 8]
>>> max(map(max, [l1, l2, l3]))
8
Combine your arrays into one, then take the min/max along the new axis.
A = np.array([a1,a2, ... , an])
A.min(axis=0), A.max(axis=0)

How to sort a list based on the output of numpy's argsort function

I have a list like this:
myList = [10,30,40,20,50]
Now I use numpy's argsort function to get the indices for the sorted list:
import numpy as np
so = np.argsort(myList)
which gives me the output:
array([0, 3, 1, 2, 4])
When I want to sort an array using so it works fine:
myArray = np.array([1,2,3,4,5])
myArray[so]
array([1, 4, 2, 3, 5])
But when I apply it to another list, it does not work but throws an error
myList2 = [1,2,3,4,5]
myList2[so]
TypeError: only integer arrays with one element can be converted to an
index
How can I now use so to sort another list without using a for-loop and without converting this list to an array first?
myList2 is a normal python list, and it does not support that kind of indexing.
You would either need to convert that to a numpy.array , Example -
In [8]: np.array(myList2)[so]
Out[8]: array([1, 4, 2, 3, 5])
Or you can use list comprehension -
In [7]: [myList2[i] for i in so]
Out[7]: [1, 4, 2, 3, 5]
You can't. You have to convert it to an array then back.
myListSorted = list(np.array(myList)[so])
Edit: I ran some benchmarks comparing the NumPy way to the list comprehension. NumPy is ~27x faster
>>> from timeit import timeit
>>> import numpy as np
>>> myList = list(np.random.rand(100))
>>> so = np.argsort(myList) #converts list to NumPy internally
>>> timeit(lambda: [myList[i] for i in so])
12.29590070003178
>>> myArray = np.random.rand(100)
>>> so = np.argsort(myArray)
>>> timeit(lambda: myArray[so])
0.42915570305194706

Python, numpy sort array

I'am using numpy and have an array (ndarray type) which contain some values. Shape of this array 1000x1500. I reshaped it
brr = np.reshape(arr, arr.shape[0]*arr.shape[1])
when I trying
brr.reverse()
AttributeError: ‘numpy.ndarray’ object has no attribute ‘reverse’
get error.
How I can sort this array ?
If you just want to reverse it:
brr[:] = brr[::-1]
Actually, this reverses along axis 0. You could also revert on any other axis, if the array has more than one.
To sort in reverse order:
>>> arr = np.random.random((1000,1500))
>>> brr = np.reshape(arr, arr.shape[0]*arr.shape[1])
>>> brr.sort()
>>> brr = brr[::-1]
>>> brr
array([ 9.99999960e-01, 9.99998167e-01, 9.99998114e-01, ...,
3.79672182e-07, 3.23871190e-07, 8.34517810e-08])
or, using argsort:
>>> arr = np.random.random((1000,1500))
>>> brr = np.reshape(arr, arr.shape[0]*arr.shape[1])
>>> sort_indices = np.argsort(brr)[::-1]
>>> brr[:] = brr[sort_indices]
>>> brr
array([ 9.99999849e-01, 9.99998950e-01, 9.99998762e-01, ...,
1.16993050e-06, 1.68760770e-07, 6.58422260e-08])
Try this for sorting in descending order ,
import numpy as np
a = np.array([1,3,4,5,6])
print -np.sort(-a)
To sort a 1d array in descending order, pass reverse=True to sorted.
As #Erik pointed out, sorted will first make a copy of the list and then sort it in reverse.
import numpy as np
import random
x = np.arange(0, 10)
x_sorted_reverse = sorted(x, reverse=True)

how to define an array in python?

i want to define an array in python . how would i do that ? do i have to use list?
Normally you would use a list. If you really want an array you can import array:
import array
a = array.array('i', [5, 6]) # array of signed ints
If you want to work with multidimensional arrays, you could try numpy.
List is better, but you can use array like this :
array('l')
array('c', 'hello world')
array('u', u'hello \u2641')
array('l', [1, 2, 3, 4, 5])
array('d', [1.0, 2.0, 3.14])
More infos there
Why do you want to use an array over a list? Here is a comparison of the two that clearly states the advantages of lists.
There are several types of arrays in Python, if you want a classic array it would be with the array module:
import array
a = array.array('i', [1,2,3])
But you can also use tuples without needing import other modules:
t = (4,5,6)
Or lists:
l = [7,8,9]
A Tuple is more efficient in use, but it has a fixed size, while you can easily add new elements to lists:
>>> l.append(10)
>>> l
[7, 8, 9, 10]
>>> t[1]
5
>>> l[1]
8
If you need an array because you're working with other low-level constructs (such as you would in C), you can use ctypes.
import ctypes
UINT_ARRAY_30 = ctypes.c_uint*30 # create a type of array of uint, length 30
my_array = UINT_ARRAY_30()
my_array[0] = 1
my_array[3] == 0

Categories

Resources