Duplicate every nth row and column of a numpy array - python

I have a given 2d np-array and want to duplicate every e.g. 3rd row and column.
Basically, if I had an np-array
a = np.array([
[1, 2, 3, 1, 2, 3],
[2, 3, 4, 2, 3, 4],
[3, 4, 5, 3, 4, 5],
[4, 5, 6, 4, 5, 6]
])
I would want to produce:
b = np.array([
[1, 2, 3, 3, 1, 2, 3, 3],
[2, 3, 4, 4, 2, 3, 4, 4],
[3, 4, 5, 5, 3, 4, 5, 5],
[3, 4, 5, 5, 3, 4, 5, 5],
[4, 5, 6, 6, 4, 5, 6, 6]
])
How could I do that?

rows
You can identify the Nth row using arithmetic, then duplicate it with np.repeat:
N = 3
out = np.repeat(a, (np.arange(a.shape[0])%N == (N-1)) + 1, axis=0)
Output:
array([[1, 2, 3, 1, 2, 3],
[2, 3, 4, 2, 3, 4],
[3, 4, 5, 3, 4, 5],
[3, 4, 5, 3, 4, 5],
[4, 5, 6, 4, 5, 6]])
intermediate:
(np.arange(a.shape[0])%N == (N-1)) + 1
# array([1, 1, 2, 1])
rows and cols
same mechanisms on both dimensions:
N = 3
rows = (np.arange(a.shape[0])%N == (N-1)) + 1
# array([1, 1, 2, 1])
cols = (np.arange(a.shape[1])%N == (N-1)) + 1
# array([1, 1, 2, 1, 1, 2])
out = np.repeat(np.repeat(a, rows, axis=0), cols, axis=1)
output:
array([[1, 2, 3, 3, 1, 2, 3, 3],
[2, 3, 4, 4, 2, 3, 4, 4],
[3, 4, 5, 5, 3, 4, 5, 5],
[3, 4, 5, 5, 3, 4, 5, 5],
[4, 5, 6, 6, 4, 5, 6, 6]])

Related

Insert an element in a list into kth position each sublist (from left to right after inserting k+=1) of another list- Python

There are 3 subsets in Spi, each subset contains its sublists and I denoted it as Spi[d][l] (d is the number of subsets and l is the number of sublists).
I want to enter each subset to insert just one specific number which is an element of S_inter into the 3rd, 4th, and 5th (3, 4, 5 are elements of in_inter_job) position of each sublist respectively.
To be more clear, that is inserting number 4 into the first subset, next is number 2 entering to the second subset (2 will be inserted into position 3 of the first sublist, position 4 in the second sublist and 5th position in the last sublist), the do the same for number 6 and the last subset.
S_inter=[4, 2, 6]
in_inter_job=[ 3, 4, 5]
Spi=[[[1, 3, 5, 2, 6], [1, 3, 5, 2, 6], [1, 3, 5, 2, 6]], [[1, 3, 5, 4, 6], [1, 3, 5, 4, 6], [1, 3, 5, 4, 6]], [[1, 3, 5, 4, 2], [1, 3, 5, 4, 2], [1, 3, 5, 4, 2]]]
The result I wanted is like :
Spi=[[[1, 3, 5, 4, 2, 6], [1, 3, 5, 2, 4, 6], [1, 3, 5, 2, 6, 4]], [[1, 3, 5, 2, 4, 6], [1, 3, 5, 4, 2, 6], [1, 3, 5, 4, 6, 2]], [[1, 3, 5, 6, 4, 2], [1, 3, 5, 4, 6, 2], [1, 3, 5, 4, 2, 6]]]
But after I run these for loop:
for d in range(0,len(Spi)):
for k in S_inter:
for l, r in zip(range(len(Spi[d])),in_inter_job):
Spi[d][l].insert(r,k)
if len(Spi[d][l]) == 6:
break
print(" After insert ",Spi)
then I get result:
Spi=[[[1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 2, 6], [1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 2, 6], [1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 2, 6]], [[1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 4, 6], [1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 4, 6], [1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 4, 6]], [[1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 4, 2], [1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 4, 2], [1, 3, 5, 6, 6, 6, 2, 2, 2, 4, 4, 2]]]
Please help me!
Simple nested for loop to insert into each list in Spi at corresponding position in in_inter_job with corresponding value in S_inter:
S_inter=[4, 2, 6]
in_inter_job=[ 3, 4, 5]
Spi=[[[1, 3, 5, 2, 6], [1, 3, 5, 2, 6], [1, 3, 5, 2, 6]], [[1, 3, 5, 4, 6], [1, 3, 5, 4, 6], [1, 3, 5, 4, 6]], [[1, 3, 5, 4, 2], [1, 3, 5, 4, 2], [1, 3, 5, 4, 2]]]
for i, x in enumerate(S_inter):
for j, L in enumerate(Spi[i]):
pos = in_inter_job[j]
L.insert(pos, x)
print(Spi)
Your zip (which is similar to what enumerate above is doing) doesn't work, because it doesn't match your logic. The positions of in_inter_job do not directly correspond with the indexes in S_inter, and so you end up inserting the wrong values, because you're trying to use the same index for both lists.

How to get data out of an array

I have an array as such from a txt file:
[[1, 4, 6, 2, 5]
[3, 4, 3, 5, 4]
[5, 3, 6, 7, 1]]
[[3, 4, 2, 5, 8]
[5, 2, 7, 5, 4]
[4, 2, 4, 4, 0]]
[[2, 5, 3, 1, 4]
[3, 8, 5, 6, 2]
[2, 6, 7, 4, 2]]
I want to take the mean of the 3rd row for each group of results. so each group is in a double bracket [[1, 4, 6, 2, 5]
[3, 4, 3, 5, 4]
[5, 3, 6, 7, 1]] is one group,
[[3, 4, 2, 5, 8]
[5, 2, 7, 5, 4]
[4, 2, 4, 4, 0]] is the second group etc.)
How do I access each group individually?
If you want to take the mean of the third row of each group with:
>>> data[:,2].mean(axis=1)
array([4.4, 2.8, 4.2])
If data is for example:
>>> data
array([[[1, 4, 6, 2, 5],
[3, 4, 3, 5, 4],
[5, 3, 6, 7, 1]],
[[3, 4, 2, 5, 8],
[5, 2, 7, 5, 4],
[4, 2, 4, 4, 0]],
[[2, 5, 3, 1, 4],
[3, 8, 5, 6, 2],
[2, 6, 7, 4, 2]]])
then by slicing, we obtain the third row of each group:
>>> data[:,2]
array([[5, 3, 6, 7, 1],
[4, 2, 4, 4, 0],
[2, 6, 7, 4, 2]])
Then for each row we can calculate the mean with .mean(axis=1)
If your data is like this, This code will work fine
lst =[
[[1, 4, 6, 2, 5],[3, 4, 3, 5, 4],[5, 3, 6, 7, 1]],
[[3, 4, 2, 5, 8],[5, 2, 7, 5, 4],[4, 2, 4, 4, 0]],
[[2, 5, 3, 1, 4],[3, 8, 5, 6, 2],[2, 6, 7, 4, 2]]
]
import numpy as np
means = []
for i in lst:
means.append(np.mean(i[2]))
print(means)
>> [4.4, 2.8, 4.2]

How to generate all possible k size vectors in a matrix (diagonals included)?

Given this matrix:
x = [[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]]
What is an efficient way to return all the possible 4 by 1 vectors and 1 by 4 matrix in this matrix. As well as any 4 diagonal spaces joined in a line.
For example:
[1,1,1,1] would appear 3 times
Diagonals also need to be addressed so [1,2,3,4] would be included as a row but also a diagonal.
Splitting the problem into two steps:
Step 1 - get all horizontal, vertical and diagonal lines
Diagonals are tackled using the fact either i+j, or respectively i-j, is constant for the indexes i, j
x = [[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]]
pprint.pprint(x)
# [[1, 2, 3, 4, 5],
# [1, 2, 3, 4, 5],
# [1, 2, 3, 4, 5],
# [1, 2, 3, 4, 5],
# [1, 2, 3, 4, 5],
# [1, 2, 3, 4, 5]]
all_lines = (
# Horizontal
[x[i] for i in range(len(x))] +
# Vertical
[[x[i][j] for i in range(len(x))] for j in range(len(x[0]))] +
# Diagonal k = i - j
[[x[k+j][j] for j in range(len(x[0])) if 0 <= k+j < len(x)] for k in range(-len(x[0])+1, len(x))] +
# Diagonal k = i + j
[[x[k-j][j] for j in range(len(x[0])) if 0 <= k-j < len(x)] for k in range(len(x[0])+len(x)-1)]
)
>>> pprint.pprint(all_lines)
[[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5],
[5],
[4, 5],
[3, 4, 5],
[2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4],
[1, 2, 3],
[1, 2],
[1],
[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[2, 3, 4, 5],
[3, 4, 5],
[4, 5],
[5]]
Step 2 - for each line select each 4-length slice
ans = [a[i:i+4] for i in range(len(a)-4+1) for a in all_lines if len(a[i:i+4]) == 4]
>>> ans = [a[i:i+4] for i in range(len(a)-4+1) for a in all_lines if len(a[i:i+4]) == 4]
>>> pprint.pprint(ans)
[[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5],
[2, 3, 4, 5],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[2, 3, 4, 5],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5]]
Maybe not be the most efficient but it's at least a way of doing it.
There will likely be a way of using itertools combinations to simplify this dramatically.

Why do all the lists in my array change when I append a new list?

I'm coding with python 3.6 and am working on a Genetic Algorithm. When generating a new population, when I append the new values to the array all the values in the array are changed to the new value. Is there something wrong with my functions?
Code:
from fuzzywuzzy import fuzz
import numpy as np
import random
import time
def mutate(parent):
x = random.randint(0,len(parent)-1)
parent[x] = random.randint(0,9)
print(parent)
return parent
def gen(cur_gen, pop_size, fittest):
if cur_gen == 1:
population = []
for _ in range(pop_size):
add_to = []
for _ in range(6):
add_to.append(random.randint(0,9))
population.append(add_to)
return population
else:
population = []
for _ in range(pop_size):
print('\n')
population.append(mutate(fittest))
print(population)
return population
def get_fittest(population):
fitness = []
for x in population:
fitness.append(fuzz.ratio(x, [9,9,9,9,9,9]))
fittest = fitness.index(max(fitness))
fittest_fitness = fitness[fittest]
fittest = population[fittest]
return fittest, fittest_fitness
done = False
generation = 1
population = gen(generation, 10, [0,0,0,0,0,0])
print(population)
while not done:
generation += 1
time.sleep(0.5)
print('Current Generation: ',generation)
print('Fittest: ',get_fittest(population))
if get_fittest(population)[1] == 100:
done = True
population = gen(generation, 10, get_fittest(population)[0])
print('Population: ',population)
Output:
Fittest: ([7, 4, 2, 7, 8, 9], 72)
[3, 4, 2, 7, 8, 9]
[[3, 4, 2, 7, 8, 9]]
[3, 4, 2, 7, 5, 9]
[[3, 4, 2, 7, 5, 9], [3, 4, 2, 7, 5, 9]]
[3, 4, 2, 7, 4, 9]
[[3, 4, 2, 7, 4, 9], [3, 4, 2, 7, 4, 9], [3, 4, 2, 7, 4, 9]]
[3, 1, 2, 7, 4, 9]
[[3, 1, 2, 7, 4, 9], [3, 1, 2, 7, 4, 9], [3, 1, 2, 7, 4, 9], [3, 1, 2, 7, 4, 9]]
[3, 1, 2, 7, 4, 2]
[[3, 1, 2, 7, 4, 2], [3, 1, 2, 7, 4, 2], [3, 1, 2, 7, 4, 2], [3, 1, 2, 7, 4, 2], [3, 1, 2, 7, 4, 2]]
[3, 1, 2, 5, 4, 2]
[[3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2]]
[3, 1, 2, 5, 4, 2]
[[3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2], [3, 1, 2, 5, 4, 2]]
[3, 1, 2, 5, 4, 5]
[[3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5], [3, 1, 2, 5, 4, 5]]
[3, 1, 2, 5, 4, 3]
[[3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3], [3, 1, 2, 5, 4, 3]]
You keep passing fittest, a reference to the same list, to mutate, which modifies the list in-place, and append it to population, so changes to the list in the next iteration are reflected across all the references to fittest in the population list.
You should pass a copy of the fittest list to mutate instead:
population.append(mutate(fittest[:]))
It's right there in the name:
def mutate(parent):
x = random.randint(0,len(parent)-1)
parent[x] = random.randint(0,9)
print(parent)
return parent
mutate isn't making a new list, it's modifying the existing list in place and returning a reference to the same list it was passed. population.append(mutate(fittest)) is happily storing aliases to fittest over and over, and since fittest is never replaced, it just keeps getting mutated and new aliases to it stored.
If the goal is to store a snapshot of the list at a given stage each time, copy it, changing:
population.append(mutate(fittest))
to:
population.append(mutate(fittest)[:])
where a complete slice of the list makes a shallow copy. population.append(mutate(fittest).copy()) would also work on modern Python, as would import copy, then doing population.append(copy.copy(mutate(fittest))) or (if the contents might themselves be mutable, though they aren't in this case) population.append(copy.deepcopy(mutate(fittest))).
Note that as a rule, Python functions aren't really supposed to both mutate and return the mutated value, as it leads to confusion like this.
Pythonic code intended to mutate in place returns None (implicitly usually, by not returning at all), so the code you'd use would actually be:
def mutate(parent):
x = random.randint(0,len(parent)-1)
parent[x] = random.randint(0,9)
print(parent)
and used with:
mutate(fittest) # Mutate fittest in place
population.append(fittest[:]) # Append copy of most recently updated fittest

Removing Element from Lists of List. PYTHON

for i in file:
file = [i.strip() for i in file]
return [file[i:i+1] for i in range(0, len(file),1)]
OUTPUT:
[['1,3,4,5,2'], ['4,2,5,3,1'], ['1,3,2,5,4'], ['1,2,4,3,5'], ['1,3,4,5,2'], ['2,1,3,5,4'], ['1,3,4,5,2'], ['3,5,2,4,1'], ['1,4,5,2,3'], ['5,1,4,3,2'], ['3,2,5,4,1'], ['3,1,2,5,4'], ['2,5,1,4,3'], ['3,2,1,4,5'], ['4,5,3,1,2'], ['1,5,4,3,2'], ['1,5,3,4,2'], ['2,1,4,3,5'], ['4,1,2,5,3']]
This is my List with sub-lists.
How can I take off the ' '? So ['1,3,4,5,2'] -> [1,3,4,5,2]
Thanks! (:
You can try this:
s = [['1,3,4,5,2'], ['4,2,5,3,1'], ['1,3,2,5,4'], ['1,2,4,3,5'], ['1,3,4,5,2'], ['2,1,3,5,4'], ['1,3,4,5,2'], ['3,5,2,4,1'], ['1,4,5,2,3'], ['5,1,4,3,2'], ['3,2,5,4,1'], ['3,1,2,5,4'], ['2,5,1,4,3'], ['3,2,1,4,5'], ['4,5,3,1,2'], ['1,5,4,3,2'], ['1,5,3,4,2'], ['2,1,4,3,5'], ['4,1,2,5,3']]
final_data = [map(int, i[0].split(",")) for i in s]
Output:
[[1, 3, 4, 5, 2], [4, 2, 5, 3, 1], [1, 3, 2, 5, 4], [1, 2, 4, 3, 5], [1, 3, 4, 5, 2], [2, 1, 3, 5, 4], [1, 3, 4, 5, 2], [3, 5, 2, 4, 1], [1, 4, 5, 2, 3], [5, 1, 4, 3, 2], [3, 2, 5, 4, 1], [3, 1, 2, 5, 4], [2, 5, 1, 4, 3], [3, 2, 1, 4, 5], [4, 5, 3, 1, 2], [1, 5, 4, 3, 2], [1, 5, 3, 4, 2], [2, 1, 4, 3, 5], [4, 1, 2, 5, 3]]
try this:
import ast
l = []
s = [['1,3,4,5,2'], ['4,2,5,3,1'], ['1,3,2,5,4'], ['1,2,4,3,5'], ['1,3,4,5,2'], ['2,1,3,5,4'], ['1,3,4,5,2'], ['3,5,2,4,1'], ['1,4,5,2,3'], ['5,1,4,3,2'], ['3,2,5,4,1'], ['3,1,2,5,4'], ['2,5,1,4,3'], ['3,2,1,4,5'], ['4,5,3,1,2'], ['1,5,4,3,2'], ['1,5,3,4,2'], ['2,1,4,3,5'], ['4,1,2,5,3']]
for li in s:
l.append(list(ast.literal_eval(li[0])))
note: ast is a built-in (standard) module if you don't know it, it cames with python installation
One line solution :
list_1=[['1,3,4,5,2'], ['4,2,5,3,1'], ['1,3,2,5,4'], ['1,2,4,3,5'], ['1,3,4,5,2'], ['2,1,3,5,4'], ['1,3,4,5,2'], ['3,5,2,4,1'], ['1,4,5,2,3'], ['5,1,4,3,2'], ['3,2,5,4,1'], ['3,1,2,5,4'], ['2,5,1,4,3'], ['3,2,1,4,5'], ['4,5,3,1,2'], ['1,5,4,3,2'], ['1,5,3,4,2'], ['2,1,4,3,5'], ['4,1,2,5,3']]
print([[int(item_3) for item_3 in item_1 if item_3.isdigit()] for item in list_1 for item_1 in item])
output:
[[1, 3, 4, 5, 2], [4, 2, 5, 3, 1], [1, 3, 2, 5, 4], [1, 2, 4, 3, 5], [1, 3, 4, 5, 2], [2, 1, 3, 5, 4], [1, 3, 4, 5, 2], [3, 5, 2, 4, 1], [1, 4, 5, 2, 3], [5, 1, 4, 3, 2], [3, 2, 5, 4, 1], [3, 1, 2, 5, 4], [2, 5, 1, 4, 3], [3, 2, 1, 4, 5], [4, 5, 3, 1, 2], [1, 5, 4, 3, 2], [1, 5, 3, 4, 2], [2, 1, 4, 3, 5], [4, 1, 2, 5, 3]]
in detailed :
for item in list_1:
for item_1 in item:
new=[]
for item_3 in item_1:
if item_3.isdigit():
new.append(int(item_3))
print(new)

Categories