简体   繁体   中英

How do I repeat binary pattern and ratio in matrix effectively in python?

I want to efficiently print a matrix in python that follows a specific pattern in the columns of 5 0s then 3 1s then 5 0s and so on and so forth as shown below for 1000 rows:

0000
0000
0000
0000
0000
1111
1111
1111
0000
0000
0000
0000
0000
1111
1111
1111
...

You can use a combination of np.block and list comprehension:

out = np.block([[np.zeros((5, 4))],[np.ones((3, 4))]] * 125).astype(int)

This can be functionalized to answer similar questions like so:

def block_repeat(size, *args):
    block = np.block([[a] for a in args])
    return np.resize(block, (size,) + block.shape[1:])

block_repeat(1000, np.zeros((5,4)), np.ones((3,4)))
Out[]: 
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       ...,
       [1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])

This didn't use numpy but it does the job. You can later convert it into a numpy matrix using numpy.matrix .

import itertools

cycle = itertools.cycle([("0") for i in range(5)] + [("1") for i in range(3)])

for i in range(1000):
  item = next(cycle)
  print(4 * item)

Output -

00000
00000
00000
00000
00000
11111
11111
11111
00000
00000
00000
00000
00000
11111
11111
11111

Here's how you can do it:

import numpy as np

my_array = np.array([[[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0], [1,1,1,1], [1,1,1,1], [1,1,1,1]] for i in range(125)])

You can check the shape. It has 125 rows of 8 rows ie 1000:

>>> my_array.shape
(125, 8, 4)

To print it you can use:

count_row = 0
for row in my_array:
    for row2 in row:
        print(row2)
        count_row += 1

Output:

# count_row is equal to 1000.

[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[1 1 1 1]
[1 1 1 1]
[1 1 1 1]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[1 1 1 1]
[1 1 1 1]
[1 1 1 1]
[0 0 0 0]
....

In the spirit of @Ishan golfing this, here it is in one line, no librarys:

print("\n".join(["00000111"[i % 8] * 4 for i in range(1000)]))

# Explanation
pattern = "00000111"
for i in range(1000):
    index = i % len(pattern)
    print(pattern[index] * 4)

Use np.tile , you can even avoid using list comprehension:

>>> unit = np.repeat([0] * 5 + [1] * 3, 4)
>>> # you can also use unit = [0] * 20 + [1] * 12,
>>> # but using ndarray as the parameter of np.tile is faster than list.
>>> np.tile(unit, 2).reshape(-1, 4)
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])
>>> np.tile(unit, 125).reshape(-1, 4)
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       ...,
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM