Cast an array shape into a string - python

I need to convert the output of a 2D array's myarray.shape into a string, because I want to isolate the rows and columns and reassign them as height and width for an image that I've read in, WITHOUT using PIL.
I tried (str)image1.shape but it just gave a syntax error.
What's the correct way to do this?

It's str(image1.shape). If you want to then parse it (say it's (50,2)), you could do this:
myshape = str(image1.shape) # returns '(50, 2)'
part1, part2 = myshape.split(', ')
part1 = part1[1:] # now is '50'
part2 = part2[:-1] # now is '2'
Or, since you're really after the numbers (I think), just skip the str() step and directly parse the output of image1.shape:
firstnum, secondnum = image1.shape
and you're done.

Related

Get string from numpy array

Im looking for an easy way to extract filename1.npy from following numpy array test:
array([['filename1.npy'],
['filename2.npy'],
['filename3.npy']],
dtype=object)
I can easily do: str(test[1]) but then I still have those brackets around it ['filename1.npy']. Though, I just want the name to insert it into np.load(path+'filename1.npy')
Thanks, for the quick response:
test[0][0]
works fine to get filename1.npy.
To loop through all names, I now use:
for index in range(3):
name = test[index]
name = name[0]
# load single file
single_file = np.load(os.path.join(path,name))

struct.pack shows shifted data

I am trying to use struct.pack to pack a hash disgest, but not getting the expected result.
This is how I am packing the data:
hash = hashlib.sha256(input).digest()
print('hash = ', hash.hex())
packed = struct.pack('!32p', hash)
print('packed = ', packed.hex())
Here is an example result:
hash = b5dbdb2b0a7d762fc7e429062d64b711d240e8f95f1c59fc28c28ac6677ffeaf
packed = 1fb5dbdb2b0a7d762fc7e429062d64b711d240e8f95f1c59fc28c28ac6677ffe
The bytes appear to be shifted, and "1f" has been added. Is this a result of an incorrect format specifier?
EDIT: I believe this first byte is the length of the data, because I am using 'p'. Is there any way to avoid this? I don't want to include this in my packed data
The 'p' format character encodes a “Pascal string” which includes the string's length at the beginning. This is documented. If you don't want that use 's' format to get just the bytes themselves instead:
packed = struct.pack('!32s', hash)
print('packed =', packed.hex())
Output:
packed = b5dbdb2b0a7d762fc7e429062d64b711d240e8f95f1c59fc28c28ac6677ffeaf

How do I get a text output from a string created from an array to remain unshortened?

Python/Numpy Problem. Final year Physics undergrad... I have a small piece of code that creates an array (essentially an n×n matrix) from a formula. I reshape the array to a single column of values, create a string from that, format it to remove extraneous brackets etc, then output the result to a text file saved in the user's Documents directory, which is then used by another piece of software. The trouble is above a certain value for "n" the output gives me only the first and last three values, with "...," in between. I think that Python is automatically abridging the final result to save time and resources, but I need all those values in the final text file, regardless of how long it takes to process, and I can't for the life of me find how to stop it doing it. Relevant code copied beneath...
import numpy as np; import os.path ; import os
'''
Create a single column matrix in text format from Gaussian Eqn.
'''
save_path = os.path.join(os.path.expandvars("%userprofile%"),"Documents")
name_of_file = 'outputfile' #<---- change this as required.
completeName = os.path.join(save_path, name_of_file+".txt")
matsize = 32
def gaussf(x,y): #defining gaussian but can be any f(x,y)
pisig = 1/(np.sqrt(2*np.pi) * matsize) #first term
sumxy = (-(x**2 + y**2)) #sum of squares term
expden = (2 * (matsize/1.0)**2) # 2 sigma squared
expn = pisig * np.exp(sumxy/expden) # and put it all together
return expn
matrix = [[ gaussf(x,y) ]\
for x in range(-matsize/2, matsize/2)\
for y in range(-matsize/2, matsize/2)]
zmatrix = np.reshape(matrix, (matsize*matsize, 1))column
string2 = (str(zmatrix).replace('[','').replace(']','').replace(' ', ''))
zbfile = open(completeName, "w")
zbfile.write(string2)
zbfile.close()
print completeName
num_lines = sum(1 for line in open(completeName))
print num_lines
Any help would be greatly appreciated!
Generally you should iterate over the array/list if you just want to write the contents.
zmatrix = np.reshape(matrix, (matsize*matsize, 1))
with open(completeName, "w") as zbfile: # with closes your files automatically
for row in zmatrix:
zbfile.writelines(map(str, row))
zbfile.write("\n")
Output:
0.00970926751178
0.00985735189176
0.00999792646484
0.0101306077521
0.0102550302672
0.0103708481917
0.010477736974
0.010575394844
0.0106635442315
.........................
But using numpy we simply need to use tofile:
zmatrix = np.reshape(matrix, (matsize*matsize, 1))
# pass sep or you will get binary output
zmatrix.tofile(completeName,sep="\n")
Output is in the same format as above.
Calling str on the matrix will give you similarly formatted output to what you get when you try to print so that is what you are writing to the file the formatted truncated output.
Considering you are using python2, using xrange would be more efficient that using rane which creates a list, also having multiple imports separated by colons is not recommended, you can simply:
import numpy as np, os.path, os
Also variables and function names should use underscores z_matrix,zb_file,complete_name etc..
You shouldn't need to fiddle with the string representations of numpy arrays. One way is to use tofile:
zmatrix.tofile('output.txt', sep='\n')

convert unicode into list

What I have when I convert an png image into blocks then add the section sign (§), I then convert it to a string using:
lframe = [e.encode('utf-8') for e in frame.split(',')]
but when I do, it gives me a:
['\xc2\xa70\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\
x88\xe2\x96\x88\xc2\xa76\xe2\x96\x88\xe2\x96\x88\xc2\xa70\xe2\x96\x88\xe2\x96\x8
8\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xc2\xa7r']
What I want to do, is to find a way to convert my output into something like
['\xc2','\xa70','\xe2','\x96','\x88'...]
Thanks!
The code below should do what you want.
lframe = [x for x in [e.encode('utf-8') for e in frame.split(',')][0]]

Horizontal flip of Image on Python with pypng

I am trying to horizontally flip an image (from left to right) on Python using PyPNG, I have written the following codes but it does not seem to work, anybody have any idea what I'm doing wrong here?
def horizontal_flip(image):
rows = len(image)
cols = len(image[0])
new_image = []
for r in range(rows):
new_row = []
for c in range(0,cols,3):
if c != cols/2:
image[c:c+3], image[-c-3: -c] = image[-c-3: -c], image[c:c+3]
new_row.append(image[r][c])
new_image.append(new_row)
return new_image
new_row.append(image[r][c]) should be outside of the if.
Also, you're flipping the image horizontally... twice. Make your for loop use range(0,cols/2,3). (That may also eliminate the need for that if.)
You're also modifying the original image in-place; are you sure you want to do that?
Seems a simpler solution might be to loop through each row in reverse, appending to a row for the new image.
The inner loop logic is wrong but particularly, this line:
image[c:c+3], image[-c-3: -c] = image[-c-3: -c], image[c:c+3]
You are changing the image variable in-place, but you seemed to forget the row variable r. So right now, you are changing rows. And your negative slicing is a bit off. For c=0, you'll get image[-3:0] and this is not a valid slice and it will return [].
But judging from your code you don't mean to change image in-place, you rather want to create new_image. What you should be doing is inserting slices at the end of new_row:
def horizontal_flip(image):
rows = len(image)
cols = len(image[0])
new_image = []
for r in range(rows):
new_row = []
for c in range(0,cols,3):
new_row = image[r][c:c+3] + new_row
new_image.append(new_row)
return new_image
By the way, you can also change the image in-place, but be careful. As you are passing a list, you should copy it before changing so that original is unchanged. Here is that version:
def horizontal_flip(image):
cols = len(image[0])/3
#make a copy so that original image is not altered
image = [row[:] for row in image]
for row in image:
for c in range(int(cols/2)): # int() is not needed for Python 2.x, since integer division yields integer
# This also takes care of odd n cases, middle chunk is not changed.
row[3*c:3*c+3], row[3*(cols-c-1):3*(cols-c-1)+3] = row[3*(cols-c-1):3*(cols-c-1)+3], row[3*c:3*c+3]
return image
This can also be done with a list comprehension in single line, but it will be less readable. If you like, here is how you can do it:
from itertools import chain
flipped_image = [list(chain(*[row[3*i:3*i+3] for i in range(len(image[0])/3-1,-1,-1)])) for row in image]

Categories