Appending to 2 dimensional array in python - python

I am reading Data from CSV file which comes similar to the below matrix/array
b = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
I would like to change the index of every element greater than 1 to a new row in the arraylist
this will make the above array as below
b = [[1,2],[5,6],[9,10],[3,4],[7,8][11,12]]
what i have done in python (but couldn't get the answer)
b = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
c = b
rows = len(b)
columns = len(b[0])
c[4].append(1)
count = 3
for i in range(rows):
for j in range(columns):
if i > 1:
for k in columns
list1 =
c.insert(count,list1)
count = count + 1

You can use numpy. Perform indexing and concatenate at the end:
import numpy as np
b = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(np.concatenate((b[:,:2], b[:,2:])))
# [[ 1 2]
# [ 5 6]
# [ 9 10]
# [ 3 4]
# [ 7 8]
# [11 12]]

data =[]
data.append(['a',1])
data.append(['b',2])
data.append(['c',3])
data.append(['d',4])
print(data)
output
[['a', 1], ['b', 2], ['c', 3], ['d', 4]]

One line solution np.array(b).reshape(-1,2):
import numpy as np
b = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
np.array(b).reshape(-1,2)
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])

Why not just split it into two lists, and then recombine them?
new_elements = []
for i in range(len(b)):
if len(b[i]) > 2:
new_elements.append(b[i][2:])
b[i] = b[i][:2]
b.extend(new_elements)

You might want to use numpy arrays and the concatenate function.
import numpy as np
b = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # or b = np.array(b)
c = np.concatenate((b[:, :2], b[:, 2:]),0)
If you prefer working with python arrays, you can use list interpretation:
c = [row[:2] for row in b]
c.extend([row[2:] for row in b])
which returns
[[1, 2], [5, 6], [9, 10], [3, 4], [7, 8], [11, 12]]

Using a list comprehension.
Ex:
b = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
n = 2
b = [j[i:i+n] for j in b for i in range(0, len(j), n)]
b = b[0::2] + b[1::2]
print(b)
Output:
[[1, 2], [5, 6], [9, 10], [3, 4], [7, 8], [11, 12]]

Another approach would be this:
b = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
step = 2
length = len(b[0])
b = [elem[i:i+step] for i in range(0,length,step) for elem in b]
print(b)
Output:
[[1, 2], [5, 6], [9, 10], [3, 4], [7, 8], [11, 12]]

Related

flatten list of numpy arrays while keeping inner arrays

l = [np.array([[1,2],[3,4]]), np.array([5,6]), np.array([[7,8],[9,10],[11,12]])]
I'm trying to flatten this list of arrays but keeping the inner arrays:
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
I tried itertools.chain, np.concatenate, np.flatten but none of these options give the output above
Your arrays have different numbers of dimensions, you need to ensure they all are 2D:
out = np.concatenate([x[None,:] if x.ndim == 1 else x for x in l])
output:
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])
or with itertools.chain with a list output:
from itertools import chain
list(chain.from_iterable([x.tolist()] if x.ndim == 1 else x.tolist()
for x in l))
output: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
You haven't provided your desired output. But, as I understood, you are looking for this:
x = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
print([n for m in x for n in m])
with output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Please let me know if this is not your desired output.
You basically need to flatten each subarray, concatenate them and finally reshape it.
np.concatenate(list(map(np.ravel, l))).reshape(-1, 2)
output:
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])

Reverse matrix diagonal

d = [[11, 2, 4], [4, 5, 6], [10, 8, -12]]
d1 = []
for i in range(n):
d1.append(arr[i][i])
d1 equals to [11, 5, -12] which is correct.
How to do a reverse matrix, I want an array with [4, 5, 10]
How can I do this with Python?
You could do it in a list comprehension using enumerate on the rows to get items from last to first column:
d = [[11, 2, 4], [4, 5, 6], [10, 8, -12]]
d1 = [row[-i] for i,row in enumerate(d,1)]
print(d1)
[4, 5, 10]
You can do d1.append(arr[i][n-i−1]) instead of d1.append(arr[i][i]).

Is there anyway to get random indexes of a list in a new list in python

I am trying to get indexes of a list store into a new list.
for example,
A = ['A', 'B', 'C',....,'Z']
and B list will select random no of indexes of A list like.
B = [[2,None,None], [1,None,None], [3,None,None],.....,[0, None,None]]
where list limit is, suppose, 10 and None will be replaced with the random no between 0 to 20 and finally the list of resultant look like,
result = [[2, 2, 3], [0, 4, 5], [8, 2, 4], [3, 8, 9]]
the first element in a sublist refers to the list A and the 2nd and third elements refer to the random selection of numbers between 0 to 10
Using random.sample.
import random
result = [random.sample(range(len(A)), 1) + random.sample(range(10), 2) for _ in range(10) ]
If you don't mind possible replication of values in the elements you can use a list comprehension, using random.randrange to generate the numbers:
result = [[random.randrange(26), random.randrange(10), random.randrange(10)] for _ in range(10)]
print(result)
Sample output:
[[18, 8, 1], [24, 1, 4], [24, 6, 5], [1, 4, 4], [7, 0, 9], [10, 7, 7], [0, 6, 9], [0, 9, 4], [6, 4, 4], [4, 2, 7]]
If you want to ensure no replication in each of elements of the list, you can use zip and random.sample to put together 3 lists of unique values and select values from those:
result = [[a, b, c] for a, b, c in zip(random.sample(range(26), 10), random.sample(range(10), 10), random.sample(range(10), 10))]
print(result)
Sample output:
[[2, 0, 1], [21, 4, 0], [11, 1, 4], [10, 7, 5], [15, 3, 3], [23, 6, 8], [25, 5, 2], [1, 9, 7], [24, 8, 9], [6, 2, 6]]
Think this basis for you
A = ['A', 'B', 'C','Z']
B = [[2,None,None], [1,None,None], [3,None,None],[0, None,None]]
for newb in B:
if newb[1] is None:
newb[1] = random.randrange(0,10)
if newb[2] is None:
newb[2] = random.randrange(0,10)
print(B)
it do like
[[2, 2, 2], [1, 6, 9], [3, 5, 7], [0, 6, 2]]

Replacing a vertical sublist in a list of lists

This question is an extension to this question.
I'm representing a two-dimensional array using list of lists, L, say:
[ [1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4] ]
For a given sub-list, say [9, 99], I want to replace a specific sub-list in the "2-D" list by this sublist using something intuitive like:
L[1][0:2] = sublist
# which updates `L` to:
[ [1, 2, 3, 4],
[1, 9, 99, 4],
[1, 2, 3, 4],
[1, 2, 3, 4] ] # not in this format, but written like this for clarity
This works for horizontal replacements, but not for vertical replacements since, as we can't slice to separate lists like this: L[0:2][0]. If I had to use this slicing system, I could transpose L (Transpose list of lists), then use this slicing method, then transpose it back. But that's not efficient, even for the sake of simplicity.
What would be an efficient way to replicate L[0:2][0] and get this output?
[ [1, 2, 3, 4],
[1, 9, 3, 4],
[1, 99, 3, 4],
[1, 2, 3, 4] ]
Note: Assume len(sublist) <= len(L), for vertical replacements (which is the focus of this question).
Looping approach:
def replaceVert(al : list, repl:list, oIdx:int, iIdx:int):
for pos in range(len(repl)):
al[oIdx+pos][iIdx] = repl[pos]
a = [ [1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16] ]
print(a) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
replaceVert(a,['ä','ü'],2,2) # this is a one liner ;)
print(a) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 'ä', 12], [13, 14, 'ü', 16]]
Transpose/slice/transpose approach:
I overread the mentioning of "no transposing". This is using transpose, change, transpose method with slicing which is not wanted by the Q. It is a answer for the title of this question, so I decided to leave it in for future people search SO and stumble over this Q:
a = [ [1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16] ]
b = list(map(list,zip(*a))) # will make [ [1,5,9,13], ... ,[4,8,12,16]]
b[1][0:2]=['a','b'] # replaces what you want here (using a and b for clarity)
c = list(map(list,zip(*b))) # inverts b back to a's form
print(a)
print(b)
print(c)
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] # a
[[1, 5, 9, 13], ['a', 'b', 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]] # b replaced
[[1, 'a', 3, 4], [5, 'b', 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] # c
Timing 4x4 list, 2 replaces:
setuptxt = """
def replaceVert(al : list, repl:list, oIdx:int, iIdx:int):
for pos in range(len(repl)):
al[oIdx+pos][iIdx] = repl[pos]
a = [ [1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16] ]
"""
zipp = """b = list(map(list,zip(*a)))
b[1][0:2]=['a','b']
c = list(map(list,zip(*b)))
"""
import timeit
print(timeit.timeit("replaceVert(a,['ä','ü'],2,2)",setup = setuptxt))
print(timeit.timeit(stmt=zipp, setup=setuptxt))
Output:
looping: 12.450226907037592
zipping: 7.50479947070815
The method wit ZIPPing (transpose/slice/transpose) needs roughly 60% of the time for 4x4 lists.
Bigger list 1000x1000 and ~70 elements replaced:
setuptxt = """
def replaceVert(al : list, repl:list, oIdx:int, iIdx:int):
for pos in range(len(repl)):
al[oIdx+pos][iIdx] = repl[pos]
a = [ [kk for kk in range(1+pp,1000+pp)] for pp in range(1,1000)]
repl = [chr(mm) for mm in range(32,100)]
"""
import timeit
print(timeit.timeit("replaceVert(a,repl,20,5)",number=500, setup = setuptxt))
zipp = """b = list(map(list,zip(*a)))
b[20][5:5+len(repl)]=repl
c = list(map(list,zip(*b)))
"""
print(timeit.timeit(stmt=zipp, setup=setuptxt,number=500))
Output:
looping: 0.07702917579216137
zipping: 69.4807168493871
Looping wins. Thanks #Sphinx for his comment

How do I convert x = [x_de,x_nu]; from matlab to python?

Given this line of matlab:
x = [x_de,x_nu];
What is the equivalent in python?
x_de and x_nu are both 3 by 9 lists of lists. For example:
x_de = [range(9), range(9), range(9)]
Python lists are concatenated with the + operator:
x = x_de + x_nu
This would concatenate "vertically".
I guess you're trying to concatenate horizontally. So you'd need to concatenate each sublist:
x = [a + b for a, b in zip(x_de, x_nu)]
Example:
x_de = [[1, 2], [3, 4], [5, 6]]
x_nu = [[7, 8], [9, 10], [11, 12]]
print x_de + x_nu
print [a + b for a, b in zip(x_de, x_nu)]
Output:
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
[[1, 2, 7, 8], [3, 4, 9, 10], [5, 6, 11, 12]]

Categories

Resources