I'm trying to create list from existing matrix:
a = matrix([[ 0, 0, 0, ..., 82, 140, 165],
[ 0, 0, 0, ..., 30925, 30830, 27075],
[ 0, 0, 0, ..., 628, 678, 528],
...,
[ 0, 0, 0, ..., 988, 930, 878],
[ 0, 1, 0, ..., 21140, 24720, 22681],
[ 0, 0, 0, ..., 1809, 1655, 1560]])
b = matrix([[ 0, 0, 0, ..., 26, 18, 14],
[ 0, 0, 0, ..., 1473, 1005, 904],
[ 0, 0, 0, ..., 138, 61, 72],
...,
[ 0, 0, 0, ..., 21, 18, 21],
[ 0, 0, 0, ..., 1036, 921, 670],
[ 0, 0, 0, ..., 176, 357, 204]])
c = matrix([[ 0, 0, 0, ..., 89, 64, 78],
[ 0, 0, 0, ..., 16346, 11977, 10209],
[ 0, 0, 0, ..., 678, 890, 1013],
...,
[ 0, 0, 0, ..., 926, 1622, 1922],
[ 0, 0, 0, ..., 5744, 6704, 9143],
[ 0, 0, 0, ..., 7, 9, 2]])
a.shape
(13, 136)
b.shape
(13, 136)
c.shape
(13, 136)
expected output: I would like to create a list of list like that
[ [a[0],b[0],c[0]], ... , [a[n],b[n],c[n]] ]
example with first and last row of each matrix:
[ [[ 0, 0, 0, ..., 82, 140, 165],[ 0, 0, 0, ..., 26, 18, 14],[ 0, 0, 0, ..., 89, 64, 78]] , ... ,[[ 0, 0, 0, ..., 1809, 1655, 1560],[ 0, 0, 0, ..., 176, 357, 204], [ 0, 0, 0, ..., 7, 9, 2]] ]
Thank you for your help
a = np.matrix([[1, 2, 3],
[12, 9, 0],
[2, 45, 2]])
b = np.matrix([[12, 9, 0],
[2, 67, 94],
[2, 45, 2]])
x = [list(t) for t in zip(a.tolist(),b.tolist())]
print(x)
Out:
[[[1, 2, 3], [12, 9, 0]], [[12, 9, 0], [2, 67, 94]], [[2, 45, 2], [2, 45, 2]]]
Related
I have a dataset organized in this way: /dataset/train/class/images.png (the same for test) (and I have 2 classes, positive and negative).
I want to obtain x_train, y_train, x_test and y_test, so I am using this python script:
x_train = []
y_train = []
x_test = []
y_test = []
base_dir_train = 'Montgomery_real_splitted/TRAIN/'
base_dir_test = 'Montgomery_real_splitted/TEST/'
for f in sorted(os.listdir(base_dir_train)):
if os.path.isdir(base_dir_train+f):
print(f"{f} is a target class")
for i in sorted(os.listdir(base_dir_train+f)):
y_train.append(f)
im = Image.open(base_dir_train+f+'/'+i)
x_train.append(im)
for f in sorted(os.listdir(base_dir_test)):
if os.path.isdir(base_dir_test+f):
print(f"{f} is a target class")
for i in sorted(os.listdir(base_dir_test+f)):
y_test.append(f)
imt=Image.open(base_dir_test+f+'/'+i)
x_test.append(imt)
y_train = np.array(y_train)
y_test = np.array(y_test)
Basically I obtain what I want, for example x_train is this:
[<PIL.PngImagePlugin.PngImageFile image mode=L size=4892x4020 at 0x10A98B280>,
<PIL.PngImagePlugin.PngImageFile image mode=L size=4020x4892 at 0x10A98B040>,
...
<PIL.PngImagePlugin.PngImageFile image mode=L size=4020x4892 at 0x11BA5D940>,
<PIL.PngImagePlugin.PngImageFile image mode=L size=4020x4892 at 0x11BA5D9A0>]
And y_train is:
array(['neg', 'neg', 'neg', 'neg', 'neg', 'neg', 'neg', 'neg', 'neg',
...
'pos', 'pos', 'pos', 'pos', 'pos', 'pos', 'pos', 'pos', 'pos'],
dtype='<U3')
However, I want that x_train is in this format:
array([[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
...
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)
How can I convert it?
EDIT for #Pyaive Oleg If I do im = np.array(im) then the result is this, which is different from the one that I want. The same for the tensor
[array([[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
...,
[ 5, 6, 7, ..., 14, 9, 5],
[ 4, 5, 6, ..., 12, 8, 4],
[ 0, 1, 2, ..., 3, 2, 0]], dtype=uint8),
array([[ 1, 1, 1, ..., 8, 246, 0],
[ 1, 1, 1, ..., 0, 7, 11],
[ 1, 1, 1, ..., 0, 0, 6],
...,
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]], dtype=uint8),
...
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]], dtype=uint8),
array([[ 0, 0, 0, ..., 0, 255, 1],
[ 0, 0, 0, ..., 0, 3, 11],
[ 0, 0, 0, ..., 2, 0, 7],
...,
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]], dtype=uint8),
array([[ 1, 1, 1, ..., 19, 246, 0],
[ 1, 1, 1, ..., 0, 16, 0],
[ 1, 1, 1, ..., 2, 0, 12],
...,
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]], dtype=uint8),
Before appending imt to x_train, do this:
imt = np.array(imt)
The following also can help:
from torchvision import transforms
imt = transforms.ToTensor()(imt)
Given these two arrays:
a = np.array(
[
[
[1, 102, 103, 255],
[201, 2, 202, 255],
[201, 202, 202, 255]
],
[
[11, 120, 0, 255],
[0, 0, 0, 255],
[1, 22, 142, 255]
],
])
b = np.array(
[
[
[1, 102, 103, 255],
[201, 2, 202, 255]
],
[
[11, 120, 0, 255],
[221, 222, 13, 255]
],
[
[91, 52, 53, 255],
[0, 0, 0, 255]
],
])
a.shape # => (2, 3, 4)
b.shape # => (3, 3, 4)
I want to overlay a and b at 0, 0 and output a mask that represents when a values equal b values. The values compared are the full pixel values, so in this case [1, 102, 103, 255] is a value.
An output mask like this would be great:
result = np.array([
[
true,
true,
false
],
[
true,
false,
false
],
[
false,
false,
false
],
])
A perfect answer in my case would be where matching values become [255, 0, 0, 255] and mismatching values become [0, 0, 0, 0]:
result = np.array([
[
[255, 0, 0, 255],
[255, 0, 0, 255],
[0, 0, 0, 0]
],
[
[255, 0, 0, 255],
[0, 0, 0, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
],
])
result.shape # => (3, 3, 4)
It looks like this:
[![diff between a and b][1]][1]
Here is one possibility using slicing.
outer = np.maximum(a.shape, b.shape)
inner = *map(slice, np.minimum(a.shape, b.shape)),
out = np.zeros(outer, np.result_type(a, b))
out[inner][(a[inner]==b[inner]).all(2)] = 255,0,0,255
out
# array([[[255, 0, 0, 255],
# [255, 0, 0, 255],
# [ 0, 0, 0, 0]],
#
# [[255, 0, 0, 255],
# [ 0, 0, 0, 0],
# [ 0, 0, 0, 0]],
#
# [[ 0, 0, 0, 0],
# [ 0, 0, 0, 0],
# [ 0, 0, 0, 0]]])
I have a .png image with four colors in it. If I convert the image to a numpy array I get an array with the following dimensions: [length X height X 3], with length == height.
How can I reduce the dimension with mapping the colors?
This is the current structure:
array([[[ 0, 65, 101],
[ 0, 65, 101],
[ 0, 65, 101],
...,
[ 0, 65, 101],
[ 0, 65, 101],
[ 0, 65, 101]],
[[ 0, 65, 101],
[163, 219, 232],
[163, 219, 232],
...,
[ 0, 65, 101],
[163, 219, 232],
[ 0, 65, 101]],
[[ 0, 65, 101],
[163, 219, 232],
[ 0, 65, 101],
...,
[ 0, 65, 101],
[163, 219, 232],
[ 0, 65, 101]],
...,
[[ 0, 65, 101],
[163, 219, 232],
[ 0, 65, 101],
...,
[ 0, 65, 101],
[ 0, 65, 101],
[ 0, 65, 101]],
[[ 0, 65, 101],
[163, 219, 232],
[163, 219, 232],
...,
[163, 219, 232],
[163, 219, 232],
[ 0, 65, 101]],
[[ 0, 65, 101],
[ 0, 65, 101],
[ 0, 65, 101],
...,
[ 0, 65, 101],
[ 0, 65, 101],
[ 0, 65, 101]]], dtype=uint8)
And I would like an array with two dimensions, and every value in the i'th row and j'th column would correspond to the color it had in the third dimension. So if the original image had 7 X 7 X 3 dimension with four colors, the output would be something like this:
array([[0, 1, 1, 3, 3, 3, 0],
[0, 2, 1, 1, 1, 1, 0],
[0, 2, 0, 1, 2, 1, 0],
[0, 3, 1, 1, 3, 1, 0],
[0, 1, 0, 0, 3, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0]])
The values in the forementioned arrays are all made up, so they don't correspond to each other, I have just tried to represent the concept.
I read the picture as:
from PIL import Image
import numpy as np
img = Image.open('image.png')
imgarray = np.asarray(img)
print(imgarray)
You can use numpy.unique for this. For example, here's a 3x5 image that has just three colors:
In [105]: img
Out[105]:
array([[[10, 20, 30],
[ 5, 5, 0],
[ 5, 5, 0],
[ 5, 5, 0],
[ 0, 0, 0]],
[[ 5, 5, 0],
[ 5, 5, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0]],
[[10, 20, 30],
[10, 20, 30],
[10, 20, 30],
[10, 20, 30],
[ 5, 5, 0]]])
Call numpy.unique on the reshaped image. The first two dimensions are flattened into a single dimension, and then axis=0 is used so we get the unique colors. inv will holds the array of "inverses", i.e. the indices into colors of the original values.
In [106]: colors, inv = np.unique(img.reshape(-1, 3), axis=0, return_inverse=True)
In [107]: colors
Out[107]:
array([[ 0, 0, 0],
[ 5, 5, 0],
[10, 20, 30]])
In [108]: inv
Out[108]: array([2, 1, 1, 1, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 1])
Reshape inv to get the array of indices into colors with the same shape as the original image:
In [109]: inv.reshape(img.shape[:2])
Out[109]:
array([[2, 1, 1, 1, 0],
[1, 1, 0, 0, 0],
[2, 2, 2, 2, 1]])
How to use one array filter out another array with non-zero value?
from numpy import array
a = array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
b = array([[0, 0, 1, 0, 0],
[0, 0, 2, 0, 0],
[0, 0, 3, 0, 0],
[0, 0, 4, 0, 0],
[0, 0, 5, 0, 0]])
Expected result:
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 7, 0, 0],
[ 0, 0, 12, 0, 0],
[ 0, 0, 17, 0, 0],
[ 0, 0, 22, 0, 0]])
Thank you
The easiest way if you want a new array would be np.where with 3 arguments:
>>> import numpy as np
>>> np.where(b, a, 0)
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 7, 0, 0],
[ 0, 0, 12, 0, 0],
[ 0, 0, 17, 0, 0],
[ 0, 0, 22, 0, 0]])
If you want to change a in-place you could instead use boolean indexing based on b:
>>> a[b == 0] = 0
>>> a
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 7, 0, 0],
[ 0, 0, 12, 0, 0],
[ 0, 0, 17, 0, 0],
[ 0, 0, 22, 0, 0]])
One line solution:
a * (b != 0)
I have a big array and a part of that is shown in small example below.
in each list, the first number is start and the 2nd number is end
(so there is a range) but each element is a part of a sequence and
each sequence starts from zero.
. what I want to do is:
small example:
array([[ 469, 1300],
[ 171, 1440],
[ 187, 1564],
[ 204, 1740],
[ 40, 1363],
[ 56, 1457],
[ 132, 606],
[1175, 2096],
[ 484, 2839],
[ 132, 4572],
[ 166, 1693],
[ 69, 3300],
[ 142, 1003],
[2118, 2118],
[ 715, 1687],
[ 301, 1006],
[ 48, 2142],
[ 63, 330],
[ 479, 2411]], dtype=uint32)
I want to take from the begining of each sequence which is indexed 0
(not included in the ranges) until -20 before
the start of each range.
I tried this code:
cds = np.column_stack([cdspos[:, 0] - cdspos[:, 0], cdspos[:, 0] - 20])
but it gives this error:
y = _nx.arange(0, num, dtype=dt)
MemoryError
but I try this one:
cds = np.column_stack([cdspos[:, 0] - 100, cdspos[:, 0] - 20])
it works perfectly. the problem is that I don't have the same range
before the starting point (all of them are not 100).
so, I want to get a smaller ranges (lists) like this: (0) to
(start-20). for example the first element would be like this:
[ 0, 449]
I also tried
cds = np.column_stack([0, cdspos[:, 0] - 20])
but did not work.
for the small example, the output I am looking for would be like this:
array([[0, 449],
[0, 151],
[0, 167],
[0, 184],
[0, 20],
[0, 36],
[0, 112],
[0, 1155],
[0, 464],
[0, 112],
[0, 146],
[0, 49],
[0, 122],
[0, 2098],
[0, 695],
[0, 281],
[0, 28],
[0, 43],
[0, 459]], dtype=uint32)
do you guys know how to do that?
What about
In [17]: numpy.array([[0, start -20] for start, end in a], dtype=numpy.uint32)
Out[17]:
array([[ 0, 449],
[ 0, 151],
[ 0, 167],
[ 0, 184],
[ 0, 20],
[ 0, 36],
[ 0, 112],
[ 0, 1155],
[ 0, 464],
[ 0, 112],
[ 0, 146],
[ 0, 49],
[ 0, 122],
[ 0, 2098],
[ 0, 695],
[ 0, 281],
[ 0, 28],
[ 0, 43],
[ 0, 459]], dtype=uint32)
Here is one way:
In [22]: np.column_stack((np.zeros(a.shape[0], dtype=np.int8), (a[:,0]- 20).astype(np.int16)))
Out[22]:
array([[ 0, 449],
[ 0, 151],
[ 0, 167],
[ 0, 184],
[ 0, 20],
[ 0, 36],
[ 0, 112],
[ 0, 1155],
[ 0, 464],
[ 0, 112],
[ 0, 146],
[ 0, 49],
[ 0, 122],
[ 0, 2098],
[ 0, 695],
[ 0, 281],
[ 0, 28],
[ 0, 43],
[ 0, 459]], dtype=int16)
Note that in this case I used np.int8 for zeros and np.int16 (or use np.uint32 if your numbers are larger to be fit on int16)for second column numbers. If you get memory error again this means that you can't preserve your arrays at once in your RAM. You can divide your array to multiple parts and apply the operations on different parts separately and process them separately too. If this is not possible