How to merge values from each array to get one new array - python

I'm trying to combine two merge values from two arrays to get one whole new array. However, I have no idea how to do.
I want to get a random float number for two variables like 5 times because I want to store them for future use. Hence, I used math.random but it doesn't work as expected because it will replace the variables.
Hence, I tried to get a randomized number and put it into an array. Then, I want to combine them to get one array. Each random number from each array are together.
import numpy as np
np.random.seed(42)
randomReleaseAngle = np.empty(5)
randomVelocity = np.empty(5)
for i in range(5):
randomReleaseAngle[i] = np.random.uniform(20.0, 77.0 )
randomVelocity[i] = np.random.uniform(40.0, 60.0 )
print(randomReleaseAngle)
print(randomVelocity)
I wanted to get something like this:
[[41.34,51.72], [28.86,45.31], [54.26,44.23], [64.22,53.29], [72.27,52.13]]

You can specify a size of the output array when using np.random.uniform, no need for looping:
randomReleaseAngle = np.random.uniform(20.0, 77.0, size=(5, 2))
randomVelocity = np.random.uniform(40.0, 60.0, size=(5, 2))
array([[41.34878677, 74.19071547],
[61.72365468, 54.1235336 ],
[28.89306251, 28.89168766],
[23.31076589, 69.37204031],
[54.26355567, 60.36013693]])

Related

How to concatenate numpy arrays to create a 2d numpy array

I'm working on using AI to give me better odds at winning Keno. (don't laugh lol)
My issue is that when I gather my data it comes in the form of 1d arrays of drawings at a time. I have different files that have gathered the data and formatted it as well as performed simple maths on the data set. Now I'm trying to get the data into a certain shape for my Neural Network layers and am having issues.
formatted_list = file.readlines()
#remove newline chars
formatted_list = list(filter(("\n").__ne__, formatted_list))
#iterate through each drawing, format the ends and split into list of ints
for i in formatted_list:
i = i[1:]
i = i[:-2]
i = [int(j) for j in i.split(",")]
#convert to numpy array
temp = np.array(i)
#t1 = np.reshape(temp, (-1, len(temp)))
#print(np.shape(t1))
#append to master list
master_list.append(temp)
print(np.shape(master_list))
This gives output of "(292,)" which is correct there are 292 rows of data however they contain 20 columns as well. If I comment in the "#t1 = np.reshape(temp, (-1, len(temp))) #print(np.shape(t1))" it gives output of "(1,20)(1,20)(1,20)(1,20)(1,20)(1,20)(1,20)(1,20)", etc. I want all of those rows to be added together and keep the columns the same (292,20). How can this be accomplished?
I've tried reshaping the final list and many other things and had no luck. It either populates each number in the row and adds it to the first dimension, IE (5840,) I was expecting to be able to append each new drawing to a master list, convert to numpy array and reshape it to the 292 rows of 20 columns. It just appears that it want's to keep the single dimension. I've tried numpy.concat also and no luck. Thank you.
You can use vstack to concatenate your master_list.
master_list = []
for array in formatted_list:
master_list.append(array)
master_array = np.vstack(master_list)
Alternatively, if you know the length of your formatted_list containing the arrays and array length you can just preallocate the master_array.
import numpy as np
formatted_list = [np.random.rand(20)]*292
master_array = np.zeros((len(formatted_list), len(formatted_list[0])))
for i, array in enumerate(formatted_list):
master_array[i,:] = array
** Edit **
As mentioned by hpaulj in the comments, np.array(), np.stack() and np.vstack() worked with this input and produced a numpy array with shape (7,20).

python efficiently applying function over multiple arrays

(new to python so I apologize if this question is basic)
Say I create a function that will calculate some equation
def plot_ev(accuracy,tranChance,numChoices,reward):
ev=(reward-numChoices)*1-np.power((1-accuracy),numChoices)*tranChance)
return ev
accuracy, tranChance, and numChoices are each float arrays
e.g.
accuracy=np.array([.6,.7,.8])
tranChance=np.array([.6,.7,8])
numChoices=np.array([2,.3,4])
how would I run and plot plot_ev over my 3 arrays so that I end up with an output that has all combinations of elements (ideally not running 3 forloops)
ideally i would have a single plot showing the output of all combinations (1st element from accuracy with all elements from transChance and numChoices, 2nd element from accuracy with all elements from transChance and numChoices and so on )
thanks in advance!
Use numpy.meshgrid to make an array of all the combinations of values of the three variables.
products = np.array(np.meshgrid(accuracy, tranChance, numChoices)).T.reshape(-1, 3)
Then transpose this again and extract three longer arrays with the values of the three variables in every combination:
accuracy_, tranChance_, numChoices_ = products.T
Your function contains only operations that can be carried out on numpy arrays, so you can then simply feed these arrays as parameters into the function:
reward = ?? # you need to set the reward value
results = plot_ev(accuracy_, tranChance_, numChoices_, reward)
Alternatively consider using a pandas dataframe which will provide clearer labeling of the columns.
import pandas as pd
df = pd.DataFrame(products, columns=["accuracy", "tranChance", "numChoices"])
df["ev"] = plot_ev(df["accuracy"], df["tranChance"], df["numChoices"], reward)

How to add a randomly generated number to elements in a pandas DataFrame

I am trying to add/subtract a random number from existing elements (floats) in a pandas DataFrame (Python).
indices is a random subset index, and modify_columns is a list of the columns I wish to modify. My DataFrame is as follows (active_set.loc[indices,modify_columns]):
Values
380977 0.0
683042 0.0
234012 0.0
16517 0.0
... ...
I would like to add or subtract a randomly generated integer (either -1 or 1) from these values.
I have tried using (2*np.random.randint(0,2,size=(count))-1) to generate an array of these random numbers, and add them:
active_set.loc[indices,modify_columns] = active_set.loc[indices,modify_columns] + (2*np.random.randint(0,2,size=(count))-1)
This does not work as there is a ValueError: Unable to coerce to Series, length must be 1: given 180. I think I can simply create a second DataFrame with the random numbers, or iterate, but these seem inefficient, and there must be a way to use .apply, so I am asking for some help on how to do this.
more general
df.loc[indexes,columns] = df.loc[indexes,columns] + 2*np.random.randint(0,50,size=(len(indexes),len(columns)))
if you want to add different random values, you can make your random.randint the same size as columns
Create array by same size like length of indices by parameter size for 2d array:
arr = 2*np.random.randint(0,2,size=(len(indices), len(modify_columns)))
active_set.loc[indices,modify_columns] += arr
The easiest solution is to use pandas.DataFrame.add function.
vector_to_add = 2*np.random.randint(0, 2, size=(count)) - 1
df.loc[indices, modify_columns] = df.loc[indices, modify_columns].add(vector_to_add, axis='index')

Efficient way to remove sections of Numpy array

I am working with a numpy array of features in the following format
[[feat1_channel1,feat2_channel1...feat6_channel1,feat1_channel2,feat2_channel2...]] (so each channel has 6 features and the array shape is 1 x (number channels*features_per_channel) or 1 x total_features)
I am trying to remove specified channels from the feature array, ex: removing channel 1 would mean removing features 1-6 associated with channel 1.
my current method is shown below:
reshaped_features = current_feature.reshape((-1,num_feats))
desired_channels = np.delete(reshaped_features,excluded_channels,axis=0)
current_feature = desired_channels.reshape((1,-1))
where I reshape the array to be number_of_channels x number_of_features, remove the rows corresponding to the channels I want to exclude, and then reshape the array with the desired variables into the original format of being 1 x total_features.
The problem with this method is that it tremendously slows down my code because this process is done 1000s of times so I was wondering if there were any suggestions on how to speed this up or alternative approaches?
As an example, given the following array of features:
[[0,1,2,3,4,5,6,7,8,9,10,11...48,49,50,51,52,53]]
i reshape to below:
[[0,1,2,3,4,5],
[6,7,8,9,10,11],
[12,13,14,15,16,17],
.
.
.
[48,49,50,51,52,53]]
and, as an example, if I want to remove the first two channels then the resulting output should be:
[[12,13,14,15,16,17],
.
.
.
[48,49,50,51,52,53]]
and finally:
[[12,13,14,15,16,17...48,49,50,51,52,53]]
I found a solution that did not use np.delete() which was the main culprit of the slowdown, building off the answer from msi_gerva.
I found the channels I wanted to keep using list comp
all_chans = [1,2,3,4,5,6,7,8,9,10]
features_per_channel = 5
my_data = np.arange(len(all_chans)*features_per_channel)
chan_to_exclude = [1,3,5]
channels_to_keep = [i for i in range(len(all_chans)) if i not in chan_to_exclude]
Then reshaped the array
reshaped = my_data.reshape((-1,features_per_channel))
Then selected the channels I wanted to keep
desired_data = reshaped[channels_to_keep]
And finally reshaped to the desired shape
final_data = desired_data.reshape((1,-1))
These changes made the code ~2x faster than the original method.
With the numerical examples, you provided, I would go with:
import numpy as np
arrays = [ii for ii in range(0,54)];
arrays = np.reshape(arrays,(int(54/6),6));
newarrays = arrays.copy();
remove = [1,3,5];
take = [0,2,4,6,7,8];
arrays = np.delete(arrays,remove,axis=0);
newarrays = newarrays[take];
arrays = list(arrays.flatten());
newarrays = list(newarrays.flatten());

Accessing specific element of an array

I'm unsure of how to access an element in an array (of arrays?). Basically, I need to be able to assign random numbers to a series of arrays but I'm not sure how indexing works.
array_20 = np.zeros((5,10))
a = [[array_20]]*10
#This gives me 10 arrays of 5x10. I'd like to be able to then assign random
#numbers to all of the elements.
You could use numpy.random.rand like so:
import numpy as np
a = np.random.rand(10, 5, 10)
You can then index a like a python list. (i.e. a[1][2][0])

Categories