Format of numpy arrays - arrays

This is a pretty easy question, I was wondering how to decipher this array:
model[Best[i][j]][6]
Is it recreating another array based off of the 'Best' array within the brackets? I'm not sure how to translate this to myself.

If we are talking about numpy arrays, this will return the value of array model positioned at Best[i][j] (this should be a number perhaps from another array) row and 6th column. Here is an example:
import numpy as np
model = np.array([[1,2],[3,4]])
Best = np.array([[0,0],[1,1]])
i = 0 # Best[i][j] is 0
j = 1
print model[Best[i][j]][1] # It prints model[0][1], which is 2

Related

Fill in numpy array using fancy indexing

Suppose I have an say NxM called Image, and I have 3 1xK arrays, x_array, y_array, z_array where x_array and y_array represent index values and z_array represents value to insert, ex:
Image[y_array[0], x_array[0]] = z_array[0]
What is the best way to do this?
You can directly index using the arrays:
Image[x_array, y_array] = z_array

Python Iterating 2D Array, Return Array Value

I have created a 2D 10x10 Array. using Numpy I want to iterate over the array as efficiently as possible.
However I would like to return the array values. essentially iterating over the 10x10 array 10 times and return a 1x10 array each time.
import datetime
import numpy as np
import random
start = datetime.datetime.now()
a = np.random.uniform(low=-1, high=1, size=(10,10))
print("Time :",datetime.datetime.now() - start)
for x in np.nditer(a):
print(x)
the result is as follows:
0.5738994777717537
0.24988408410910767
0.8391827831682657
0.0015975845830569213
0.54477459840569
0.14091622639476165
-0.36517132895234106
-0.06311125453484467
-0.6572544506539948
...
100 times
However I would expect the result to be:
[0.5738994777717537,
0.24988408410910767,
0.8391827831682657,
0.0015975845830569213,
0.54477459840569,
0.14091622639476165,
-0.36517132895234106,
-0.06311125453484467,
-0.6572544506539948],[...]
...
10 times
Any help would be appreciated!
To directly answer your question, this does exactly what you want:
import numpy as np
a = np.random.uniform(low=-1, high=1, size=(10,10))
print(','.join([str(list(x)) for x in a]))
This will print
[-0.2403881196886386, ... , 0.8518165986395723],[-0.2403881196886386, ... , 0.8518165986395723], ..., [-0.2403881196886386, ... , 0.8518165986395723]
The reason you're printing just the elements of the array is due to the way nditer works. nditer iterates over single elements, even at a multidimensional level, whereas you want to iterate over just the first dimension of the array. For that, for x in a: works as intended.
Edit
Here is a good link if you want to read up on how nditer works: https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#arrays-nditer

How to structure multiple python arrays for sorting

A fourier analysis I'm doing outputs 5 data fields, each of which I've collected into 1-d numpy arrays: freq bin #, amplitude, wavelength, normalized amplitude, %power.
How best to structure the data so I can sort by descending amplitude?
When testing with just one data field, I was able to use a dict as follows:
fourier_tuples = zip(range(len(fourier)), fourier)
fourier_map = dict(fourier_tuples)
import operator
fourier_sorted = sorted(fourier_map.items(), key=operator.itemgetter(1))
fourier_sorted = np.argsort(-fourier)[:3]
My intent was to add the other arrays to line 1, but this doesn't work since dicts only accept 2 terms. (That's why this post doesn't solve my issue.)
Stepping back, is this a reasonable approach, or are there better ways to combine & sort separate arrays? Ultimately, I want to take the data values from the top 3 freqs and associated other data, and write them to an output data file.
Here's a snippet of my data:
fourier = np.array([1.77635684e-14, 4.49872050e+01, 1.05094837e+01, 8.24322470e+00, 2.36715913e+01])
freqs = np.array([0. , 0.00246951, 0.00493902, 0.00740854, 0.00987805])
wavelengths = np.array([inf, 404.93827165, 202.46913583, 134.97942388, 101.23456791])
amps = np.array([4.33257766e-16, 1.09724890e+00, 2.56328871e-01, 2.01054261e-01, 5.77355886e-01])
powers% = np.array([4.8508237956526163e-32, 0.31112370227749603, 0.016979224022185751, 0.010445983875848858, 0.086141014686372669])
The last 4 arrays are other fields corresponding to 'fourier'. (Actual array lengths are 42, but pared down to 5 for simplicity.)
You appear to be using numpy, so here is the numpy way of doing this. You have the right function np.argsort in your post, but you don't seem to use it correctly:
order = np.argsort(amplitudes)
This is similar to your dictionary trick only it computes the inverse shuffling compared to your procedure. Btw. why go through a dictionary and not simply a list of tuples?
The contents of order are now indices into amplitudes the first cell of order contains the position of the smallest element of amplitudes, the second cell contains the position of the next etc. Therefore
top5 = order[:-6:-1]
Provided your data are 1d numpy arrays you can use top5 to extract the elements corresponding to the top 5 ampltiudes by using advanced indexing
freq_bin[top5]
amplitudes[top5]
wavelength[top5]
If you want you can group them together in columns and apply top5 to the resulting n-by-5 array:
np.c_[freq_bin, amplitudes, wavelength, ...][top5, :]
If I understand correctly you have 5 separate lists of the same length and you are trying to sort all of them based on one of them. To do that you can either use numpy or do it with vanilla python. Here are two examples from top of my head (sorting is based on the 2nd list).
a = [11,13,10,14,15]
b = [2,4,1,0,3]
c = [22,20,23,25,24]
#numpy solution
import numpy as np
my_array = np.array([a,b,c])
my_sorted_array = my_array[:,my_array[1,:].argsort()]
#vanilla python solution
from operator import itemgetter
my_list = zip(a,b,c)
my_sorted_list = sorted(my_list,key=itemgetter(1))
You can then flip the array with my_sorted_array = np.fliplr(my_sorted_array) if you wish or if you are working with lists you can reverse it in place with my_sorted_list.reverse()
EDIT:
To get first n values only, you have to simply slice the array similarly to what #Paul is suggesting. Slice is done in a similar manner to classic list slicing by specifying start:stop:step (you can omit the step) arguments. In your case for 5 top columns it would be [:,-5:]. So in the example above you can take top 2 columns from each row like this:
my_sliced_sorted_array = my_sorted_array[:,-2:]
result will be:
array([[15, 13],
[ 3, 4],
[24, 20]])
Hope it helps.

Numpy array with symmetric indices

How do I create a numpy array with a symmtric range of indices?
I tried:
np.zeros(-100:100,-100:100)
expecting an array with index -100 to +100.
NumPy doesn't have support for this; indexing always starts at zero. You could try writing your own subclass of ndarray, but you'd have a lot of awkward design decisions to make; for example, if you have an array with indices from -100 to 100, where do the indices of array[1:] start and end? And how do you broadcast operations across arrays with compatible shapes, but different indices? What would the bounds be of the result of something like dot?
After some searching I found this. I really didn't need a symmetrical array index. What I wanted was a way to simply specify a circular aperture without an x,y loop. I really don't understand what this ogrid thingy does, but it works.
Cheers,
Gert
import numpy as np
import matplotlib.pyplot as plt
r= 800
s= 1000
y,x = np.ogrid[-s:s+1, -s:s+1]
mask = x*x + y*y <= r*r
aperture = np.ones((2*s+1, 2*s+1))
aperture[mask] = 0
plt.imshow(aperture)
plt.show()

Numpy array - multiplying each column by one another

I would like to know the fastest way to multiply each column of a numpy array by one another and return a new numpy array consisting of these just-built columns - all 2-element combinations from n-element set of columns.
This should be a good starting point
import numpy as np
I, J = np.triu_indices(n)
A[:,I] * A[:,J]

Resources