numpy:Change values in array by randomly differently selecting index - python

I am new in numpy, and I am having troubles with simple managment of numpy arrays.
I am doing a task in which it said that randomly daily select different 12 items in a numpy by index to change its value.
import numpy as np
import random
N = 20
s = np.zeros([N])
for t in range(12):
randomindex = random.randint(0,len(s)-1)
s[randomindex] = 10
thanks for u answering .I'm sorry for my describing,i'm not good at how writting problem of python by english.--!.I will give more detailed information
e.g. s=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
and i randomly choose a item from its numpy by its index ,
randomindex=random.randint(0,len(s)-1),
randomindex will be 0-19,
and s(randomindex)=10,if the randomindex is 2 means s(2) is 10,
s=(1,2,10,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20).
And if i want choose 3 items, i do 3 times'for',how can i everytimes choose different index changes its value in numpy.
and daily which means i will give sum the new s and given to a new numpy R[T]
like:
import numpy as np
import random
N = 20
s = np.zeros([N])
T=10 #DAY
R = np.zereos([T])
for t in range(T-1):
R[T+1]=R[T]+R[T]*3
for t in range(12):
randomindex = random.randint(0,len(s)-1)
s[randomindex] = 10
R[T]=np.sum(s)

I'm having a little difficulty understanding what you're asking, but I think you want a way to be selecting different values in a randomized order. And the problem with the above code is that you may be getting duplicates.
I have two solutions. One, you can use the Python random library. The Python random.shuffle function will randomly shuffle all the values in an iterable (such as a list or array). You can then proceed to access them sequentially as you normally would. Here's an example of Random Shuffle.
list1 = ["Apple", "Grapes", "Bananas","Grapes"]
random.shuffle(list1)
print(list1)
The second solution doesn't involve the use of a library. You can simply make an addition into the code above. Create a new empty list, and every time you retrieve a value add it into this list. Also, whenever you retrieve a value check to see whether it's already located in the list. For instance, if you retrieve the value 5, add it to the list. If later on, you end up with the value 5 again, run a check through the list and you will find that 5 already exists in it. You can then reset that iteration and take input again.
You can append to a list with the following code.
newlist = ["Python", "Java","HTML","CSS"]
newlist.append("Ruby")
print(newlist)

Related

Assign values to different index positions as the actual in a loop python

I have the next variables which are List, floats and a numpy array.
dt=list(range(1,12))
c=18
limit=2.75
Energy=np.zeros(len(dt))
I want to assign the value c=18 in the Numpy array Energy. However, there is a condition. The value in the Energy vector can not be greater than limit=2.75, so as c=18 is greater than limit=2.75, it should be cut to 2.5 and assigned in the actual index position of the loop and in the next index positions of the vector Energy until the value 18 is reached. I made this code but it does not really work efficiently.
for i in range(0,1):
if c>limit:
tmp2=c-(limit)
if tmp2>(limit):
tmp3=tmp2-(limit)
if tmp3>limit:
tmp4=tmp3-(limit)
if tmp4>(limit):
tmp5=tmp4-(limit)
if tmp5>(limit):
tmp6=tmp5-(limit)
if tmp6>limit:
tmp7=tmp6-(limit)
if tmp7>(limit):
tmp8=tmp7-(limit)
else:
Energy[i]=limit
Energy[i+1]=limit
Energy[i+2]=limit
Energy[i+3]=limit
Energy[i+4]=limit
Energy[i+5]=limit
Energy[i+6]=tmp7
Do you have an idea of how to make it better? Thank you!
Welcome to stackoverflow!
Your code presently uses a loop where it doesn't need one and doesn't use a loop where it could be used.
Stepping into your code:
for i in range(0,1):
If we change this to:
for i in range(0,1):
print (i)
We will get the result 0 - it only runs once so there is no need to loop it - i isn't referred to in your code so there is no need to loop through it.
You could use a loop to allocate your c to an array but it isn't needed and I'll leave that as an exercise for yourself.
It can be approached in a different, more efficient way.
First of all when you're assigning variables try and make them descriptive and readable - you'll spend a lot more time coming back to code than you do reading it.
I don't know what system you're describing so I've just given generic names:
import numpy as np
length_arrary=12
limit=2.75
value_to_be_assigned=18
energy_result=np.zeros(length_arrary)
Now what we are really asking is two things, how many times does value_to_be_assigned divide into the limit (an integer) and what is the remainder.
Python has two operations for this floor division (//) and modulus which give:
11//5 = 2.0
1%5 = 1.0
So we know the first (value_to_be_assigned//limit elements - 1) of the array need to be equal to the limit and the final element needs to be equal to value_to_be_assigned % limit
Finally Python has an easy way to access elements of a list - we can set the first x elements to be equal to a value with:
array[:x]=value
x just needs to be an integer.
Putting it together we get:
filled_values=int(value_to_be_assigned//limit)
energy_result[:filled_values]=limit
energy_result[filled_values] = value_to_be_assigned % limit
and we can check with
energy_result.sum() # gives us 18

Why I'm Getting Single Element Instead of 10 When Running This Command

Tried a lot but I'm not able to cast the whole elements into array,I want 10 elements in my 1D Array
I Use This Code
import numpy as np
list1=np.random.randint(low=50,high=100,size=50).reshape(10,5)
for i in list1.flat:
print(i)
list2=np.array(i,dtype=int)
list2
To See The Output >>>>>>
Refer To this pic
I'm always getting 1 element as output instead of 10 elements
Please Suggest Only Modification Into This Code
I'm assuming since you know about np.reshape you have some reason to need to use a loop?
Assuming that's true, you can instantiate list2 outside of the loop and then append values inside the loop. Right now you are making a new np array every time you go through the loop, hence on leaving the loop you simply have a new np array with the final value.
I.e.
list2 = np.array(np.zeros(50))
j = 0
for i in list1.flat:
list2[j] = i
j+=1
I have to agree with #Piinthesky that your problem is not well formulated. I suspect (but I am not sure) that you want to obtain a flattened (1D) version of the 2D array list1. Please refer to https://stackoverflow.com/a/28930580/8033585 for more details on differences between ravel, reshape, and flatten.
Thus, you can get a flattened array as:
Method 1:
list2 = list1.reshape(-1) # returns a view! modifying list2 modifies list1
Method 2:
list2 = list1.ravel() # returns a view most of the time (unless list1 is not contiguous)!
Method 3:
list2 = list1.flatten() # returns a 1D **copy** of list1
Since your question is not clear i assumed you have given reshape(10,5) that will caste data always in 5 columns
if i understood right. try this:-
import numpy as np
list1=np.random.randint(low=50,high=100,size=50).reshape(5,10)
for i in list1:
print (i)

Insert an element in la list by index without moving others

I want to add elements to an empty list by index. For instance I want to add 4 to the 5th place of list a.
x = 4
a = []
in other languages like C++ I could create an array with 10 indices and all empty at first and then write something like:
a[5] = 4
But I could not find the same in python. I just found insert method which moves the next elements one index in every insertion (right?). This I must really avoid.
Maybe I need to remove one element and then insert another element, I don't know. I really appreciate your help, I am really stuck here.
As #Jakub stated, you can pre-allocate your list with values.
a = [None] * 5
Then, simply use python's list index notation to change an element's value.
a[3] = 31
If you like Numpy way of doing it, you can use the following
import numpy as np
a= np.empty(5)
Then, you can assign values normally.
a[0]=4
Then you can convert this array into a list using
a= a.tolist()

Efficient Array replacement in Python

I'm wondering what is the most efficient way to replace elements in an array with other random elements in the array given some criteria. More specifically, I need to replace each element which doesn't meet a given criteria with another random value from that row. For example, I want to replace each row of data as a random cell in data(row) which is between -.8 and .8. My inefficinet solution looks something like this:
import numpy as np
data = np.random.normal(0, 1, (10, 100))
for index, row in enumerate(data):
row_copy = np.copy(row)
outliers = np.logical_or(row>.8, row<-.8)
for prob in np.where(outliers==1)[0]:
fixed = 0
while fixed == 0:
random_other_value = r.randint(0,99)
if random_other_value in np.where(outliers==1)[0]:
fixed = 0
else:
row_copy[prob] = row[random_other_value]
fixed = 1
Obviously, this is not efficient.
I think it would be faster to pull out all the good values, then use random.choice() to pick one whenever you need it. Something like this:
import numpy as np
import random
from itertools import izip
data = np.random.normal(0, 1, (10, 100))
for row in data:
good_ones = np.logical_and(row >= -0.8, row <= 0.8)
good = row[good_ones]
row_copy = np.array([x if f else random.choice(good) for f, x in izip(good_ones, row)])
High-level Python code that you write is slower than the C internals of Python. If you can push work down into the C internals it is usually faster. In other words, try to let Python do the heavy lifting for you rather than writing a lot of code. It's zen... write less code to get faster code.
I added a loop to run your code 1000 times, and to run my code 1000 times, and measured how long they took to execute. According to my test, my code is ten times faster.
Additional explanation of what this code is doing:
row_copy is being set by building a new list, and then calling np.array() on the new list to convert it to a NumPy array object. The new list is being built by a list comprehension.
The new list is made according to the rule: if the number is good, keep it; else, take a random choice from among the good values.
A list comprehension walks over a sequence of values, but to apply this rule we need two values: the number, and the flag saying whether that number is good or not. The easiest and fastest way to make a list comprehension walk along two sequences at once is to use izip() to "zip" the two sequences together. izip() will yield up tuples, one at a time, where the tuple is (f, x); f in this case is the flag saying good or not, and x is the number. (Python has a built-in feature called zip() which does pretty much the same thing, but actually builds a list of tuples; izip() just makes an iterator that yields up tuple values. But you can play with zip() at a Python prompt to learn more about how it works.)
In Python we can unpack a tuple into variable names like so:
a, b = (2, 3)
In this example, we set a to 2 and b to 3. In the list comprehension we unpack the tuples from izip() into variables f and x.
Then the heart of the list comprehension is a "ternary if" statement like so:
a if flag else b
The above will return the value a if the flag value is true, and otherwise return b. The one in this list comprehension is:
x if f else random.choice(good)
This implements our rule.

Storing multiple arrays in Python

I am writing a program to simulate the actual polling data companies like Gallup or Rasmussen publish daily: www.gallup.com and www.rassmussenreports.com
I'm using a brute force method, where the computer generates some random daily polling data and then calculates three day averages to see if the average of the random data matches pollsters numbers. (Most companies poll numbers are three day averages)
Currently, it works well for one iteration, but my goal is to have it produce the most common simulation that matches the average polling data. I could then change the code of anywhere from 1 to 1000 iterations.
And this is my problem. At the end of the test I have an array in a single variable that looks something like this:
[40.1, 39.4, 56.7, 60.0, 20.0 ..... 19.0]
The program currently produces one array for each correct simulation. I can store each array in a single variable, but I then have to have a program that could generate 1 to 1000 variables depending on how many iterations I requested!?
How do I avoid this? I know there is an intelligent way of doing this that doesn't require the program to generate variables to store arrays depending on how many simulations I want.
Code testing for McCain:
test = []
while x < 5:
test = round(100*random.random())
mctest.append(test)
x = x +1
mctestavg = (mctest[0] + mctest[1] + mctest[2])/3
#mcavg is real data
if mctestavg == mcavg[2]:
mcwork = mctest
How do I repeat without creating multiple mcwork vars?
Would something like this work?
from random import randint
mcworks = []
for n in xrange(NUM_ITERATIONS):
mctest = [randint(0, 100) for i in xrange(5)]
if sum(mctest[:3])/3 == mcavg[2]:
mcworks.append(mctest) # mcavg is real data
In the end, you are left with a list of valid mctest lists.
What I changed:
Used a list comprehension to build the data instead of a for loop
Used random.randint to get random integers
Used slices and sum to calculate the average of the first three items
(To answer your actual question :-) ) Put the results in a list mcworks, instead of creating a new variable for every iteration
Are you talking about doing this?
>>> a = [ ['a', 'b'], ['c', 'd'] ]
>>> a[1]
['c', 'd']
>>> a[1][1]
'd'
Lists in python can contain any type of object -- If I understand the question correctly, will a list of lists do the job? Something like this (assuming you have a function generate_poll_data() which creates your data:
data = []
for in xrange(num_iterations):
data.append(generate_poll_data())
Then, data[n] will be the list of data from the (n-1)th run.
since you are thinking in variables, you might prefer a dictionary over a list of lists:
data = {}
data['a'] = [generate_poll_data()]
data['b'] = [generate_poll_data()]
etc.
I would strongly consider using NumPy to do this. You get efficient N-dimensional arrays that you can quickly and easily process.
A neat way to do it is to use a list of lists in combination with Pandas. Then you are able to create a 3-day rolling average.
This makes it easy to search through the results by just adding the real ones as another column, and using the loc function for finding which ones that match.
rand_vals = [randint(0, 100) for i in range(5))]
df = pd.DataFrame(data=rand_vals, columns=['generated data'])
df['3 day avg'] = df['generated data'].rolling(3).mean()
df['mcavg'] = mcavg # the list of real data
# Extract the resulting list of values
res = df.loc[df['3 day avg'] == df['mcavg']]['3 day avg'].values
This is also neat if you intend to use the same random values for different polls/persons, just add another column with their real values and perform the same search for them.

Categories