Array problems in for loop - python

I want to go from one array A of 10 elements to the array B of 100 elements.
Each element of B from 0 to 9 is equal to the element 0 of A
Each element of B from 10 to 19 is equal to the element 1 of A
....
Each element of B from 90 to 99 is equal to the element 9 of A
I did the following code but it does not work
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
A = np.asarray(a)
b = []
for i in range(len(A)*10):
b.append(0)
B = np.asarray(b)
for i in range(len(A)):
for j in range(9):
B[j]=A[i]
Expected result:
B [ 0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2
...,
9,9,9,9,9,9,9,9,9,9 ]

You are saving values only in first 9 list elements. You have to 'scale' it by adding i*10 to index.
import numpy as np
a=[0, 1, 2, 3, 4, 5, 6, 7]
A = np.asarray(a)
b = []
for i in range(len(A)**2):
b.append(0)
B = np.asarray(b)
for i in range(len(A)):
for j in range(len(A)):
B[j + i*len(A)]=A[i]
print(B)

This works for me:
>>> a = [1,2,3]
>>> [ x for i in a for x in [i]*3]
[1, 1, 1, 2, 2, 2, 3, 3, 3]
>>>
You may replace 3 with 10 or whatever you like.
Answering the question from Jacob:
>>> [[a]*10 for a in A]
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]]

You should avoid loops with numpy whenever possible. It kind of defeats the point. Here you can just use repeat():
import numpy as np
a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
A = np.asarray(a)
B = A.repeat(10)
B:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9])
If want the a nested list, just reshape:
B = A.repeat(10).reshape(-1, 10)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]])

You can use numpy and specify how many iterations of each element you want:
import numpy as np
A = [1,2,3,4]
B = [np.full(10, a) for a in A]
print(B)
Or if you prefer to not use numpy, instead use:
A = [1,2,3,4]
B = [[a]*10 for a in A]
print(B)
Giving you the wanted list B

Try this:
a = [*range(10)]
b = []
for i in range(10):
b.extend([a[i]* 10])
B = np.asarray(b)

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = []
for x in a:
b += [x] * 10
print b
This answer is better, idea from lenik
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [x for x in a for i in range(10)]
print b

Answer in a single line: print([item for sublist in [[i]*10 for i in range(1,10)] for item in sublist])

If a were a generic list and not an ordered sequence
In [20]: a = [1, 'a', 3.14159, False, {1:2, 3:4}]
you could do as follows
In [21]: [_ for _ in (zip(*(a for _ in a))) for _ in _]
Out[21]:
[1,
1,
1,
1,
1,
'a',
'a',
'a',
'a',
'a',
3.14159,
3.14159,
3.14159,
3.14159,
3.14159,
False,
False,
False,
False,
False,
{1: 2, 3: 4},
{1: 2, 3: 4},
{1: 2, 3: 4},
{1: 2, 3: 4},
{1: 2, 3: 4}]

list1=[]
list2=[]
for i in range (0,10,1):
list1.append(i)
print(list1)
for i in range (0,10,1):
for j in range (0,10,1):
j=i
list2.append(j)
print(list2)

Related

Copy an Array and delete doubles

I got this code
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9]
B = [0 for b in range(16)]
skipped = 0
for i in range(16):
if A[i] == A[i-1]:
skipped += 1
else:
B[i-skipped] = A[i]
print(B)
The output:
[1, 2, 3, 4, 5, 2, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0]
it eliminates the doubles. But if i got an array where doubles are at more random index it fails, like:
The Array#2:
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 2, 2, 2, 7, 8, 8, 9]
The output#2
[1, 2, 3, 4, 5, 2, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0]
In the output#2 there is the value 2 at index 1 and index 5, but i just want to eliminate all the doubles.
Sum:
So basically my algorithm should copy the values from Array A to Array B and eliminate all doubles independent from their index.
EDIT: i have to put it in pseudocode so i cant use convert methods or functions like SET
You can use set to do it:
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9]
B = set(A)
print(B)
This code returns a set. To convert set to list you can write some_list = list(B).
Another way to do what you need:
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9]
B = []
for x in A:
if x not in B:
B.append(x)
print(B)

sample n random permutations of a list in python [duplicate]

This question already has answers here:
python shuffling with a parameter to get the same result
(4 answers)
Closed 1 year ago.
I have a list of values such as:
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
and I need to reproducibly return n random shuffles of this list.
Ideally, I need a function with seed such that f(lst, samples = 2, seed = 1234)
-> return two shuffles of the list lst such as:
[5, 7, 1, 6, 2, 8, 0, 4, 3, 9]
[8, 7, 3, 0, 1, 4, 5, 9, 6, 2]
Repeated execution of this function (with the same seed) would return the same two lists.
This works without numpy:
import sys
import random
some_seed = 123 # change this to get different shuffles
def n_shuffles(lst, n):
r = random.Random(some_seed)
for _ in range(n):
_l = lst[:]
r.shuffle(_l)
yield _l
l = list(range(10))
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
You can use np.copy
import numpy as np
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def shuffle_list(arr:list,samples:int,seed:int):
np.random.seed(seed)
res = []
for i in range(samples):
arr_copy=np.copy(arr)
np.random.shuffle(arr_copy)
res.append(arr_copy)
return res
#test
print(shuffle_list(lst,2,1234))
output:
[array([7, 2, 9, 1, 0, 8, 4, 5, 6, 3]), array([7, 3, 5, 1, 4, 8, 0, 2, 6, 9])]
Ok, it wasn't an exact duplicate, but the proposed topic has pretty much shown that re-setting the seed() is the key:
import random
def shuffles(l,n):
random.seed(4) # just the same one as in the referred topic
return [random.sample(l,k=len(l)) for i in range(n)]
print(shuffles([1,2,3,4],3))
print("again:")
print(shuffles([1,2,3,4],3))
will generate
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]
again:
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]

Return a dict containing the first N list entries for each key from a dict of lists

Consider the following dictionary of lists, d:
{
'ra': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'decl': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'source_id': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'priority': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
}
I would like to return a dictionary containing <= the first N values in the list for every dictionary key. Hence if N = 4, it should return
{
'ra': [0, 1, 2, 3],
'decl': [0, 1, 2, 3],
'source_id': [0, 1, 2, 3],
'priority': [0, 1, 2, 3],
}
or if the list is shorter than 4 entries, to return the full list. A bit like .head(N) works for data frames.
I can convert the dictionary to a data frame, perform the .head(N) operation and convert it back to a dict, but it seems like there must be an easier/more Pythonic way to do this.
I'd go for something using dict comprehension
lessen = {
'ra': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'decl': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'source_id': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'priority': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
}
limit = 4
new = {k:v[:limit] for k,v in lessen.items()}
output
{'ra': [0, 1, 2, 3], 'decl': [0, 1, 2, 3], 'source_id': [0, 1, 2, 3], 'priority': [0, 1, 2, 3]}
It's fairly easy to do with a simple for loop:
N = 4
for key in thedata:
thedata[key] = thedata[key][:N]
You may use
dct = {
'ra': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'decl': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'source_id': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'priority': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
}
new_dct = {key: values[0:4] for key, values in dct.items()}
print(new_dct)

How to duplicate a NumPy array to form a new array with several rows of the original array? [duplicate]

This question already has an answer here:
Numpy - create matrix with rows of vector
(1 answer)
Closed 2 years ago.
I want to create a NumPy array by duplicating another array by a few rows. I did it as shown below. Is there a NumPyier way of doing this?
>>> a = np.arange(0,10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = tuple( a for _ in range(3) )
>>> b
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
>>> c = np.vstack( b )
>>> c
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
I found a way to do it. Sharing it here.
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[None,:]
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> np.repeat( a[None,:], 3, axis=0 )
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])

Python Array Index - Every X elements?

So I have a weird problem...
I'd like to process an array and take naturally rounded indices's out of it.
For example, if you have array...
pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
I'd like to take every 1.1st element out of it rounded naturally. So under this case:
pies[0::round(1.1x)]
Would output:
[0, 1, 2, 3, 4, 6, 7, 8, 9]
Because it would take out the following rounded positions:
pies[0]->pies[0]
pies[1.1]->pies[1]
pies[2.2]->pies[2]
pies[3.3]->pies[3]
pies[4.4]->pies[4]
pies[5.5]->pies[6]
pies[6.6]->pies[7]
pies[7.7]->pies[8]
pies[8.8]->pies[9]
Note we're not rounding the content - we're rounding the index.
As another example, consider:
pies = [0, 2, 5, 1, 3, 9, 2, 12, 33, 45]
pies[0::round(1.1x)]
Would output:
[0, 2, 5, 1, 3, 2, 12, 33, 45]
I'm wondering how you could do this in the most 'pythonic' way possible.
Thanks!
In [7]: pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [8]: stride=1.1
In [9]: [pies[x] for x in range(len(pies)) for x in [int(round(x*stride))] if x < len(pies)]
Out[9]: [0, 1, 2, 3, 4, 6, 7, 8, 9]
In the alternative, this seems like a good job for a generator function:
def rounding_iterator(seq, stride):
try:
i = 0
while True:
yield seq[int(round(i*stride))]
i += 1
except IndexError:
pass
pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(rounding_iterator(pies, 1))
print list(rounding_iterator(pies, 1.1))
print list(rounding_iterator(pies, .9))
Result:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]
How about multiplying the value in the list by 1.1, rounding it, and converting it to an int to drop the decimal:
pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for pie in pies:
print int(round(pie * 1.1))
If it doesn't need to be one line...
def rounded_indices(ls):
result = []
original_index = 0
new_index = 0
while new_index < len(ls):
result.append(ls[new_index])
original_index += 1
new_index = int(round(1.1 * original_index))
return result
>>> pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> rounded_indices(pies)
[0, 1, 2, 3, 4, 6, 7, 8, 9]
I've edited this, so you need increment index with 1.1 and round it. Correct?
If so, it should be something like this:
>>> pies = [0, 1, 2, 3, 3, 2, 1, 77, 88, 99]
>>> print [ pies[int(round(x*0.1+x))] for x in xrange(len(pies)-1) ]
[0, 1, 2, 3, 3, 1, 77, 88, 99]
>>> pies = [0, 2, 5, 1, 3, 9, 2, 12, 33, 45]
>>> print [ pies[int(round(x*0.1+x))] for x in xrange(len(pies)-1) ]
[0, 2, 5, 1, 3, 2, 12, 33, 45]
>>>
Does this, what you want?
Same with numpy:
>>> import numpy as np
>>> pies = [0, 2, 5, 1, 3, 9, 2, 12, 33, 45]
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)-1,1.1) ]
[0, 2, 5, 1, 3, 2, 12, 33, 45]
With numpy you can change multiplier:
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)/1.1,1.1) ]
[0, 2, 5, 1, 3, 2, 12, 33, 45]
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)/3.3,3.3) ]
[0]
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)/2.2,2.2) ]
[0, 5, 3]
>>>

Categories

Resources