Harsh Wardhan Harsh Wardhan - 7 months ago 16
Python Question

How to write a string and a numpy array in a file?

I am computing features for images read from a directory and I want to write the image path and the corresponding features in a file, separated by spaces. The output is desired in this fashion

/path/to/img1.jpg 1 0 0 1 3.5 0.2 0
/path/to/img2.jpg 0 0 0.5 2.1 0 0.7
...


Following is part of my code

features.open('file.txt', 'w')
for fname in fnmatch.filter(fileList, '*.jpg'):
image = '/path/to/image'
# All the operations are here
myarray = [......] # array of dimensions 512x512
myarray.reshape(1, 512*512) # Reshape to make it a row vector
features.write(image + ' '.join(str(myarray)))
features.write('\n')
features.close()


But the output is coming as

/path/to/img1.jpg[[0 0 1.0 2 3]]
/path/to/img2.jpg[[1.2 0 1.0 2 0.3]]

Answer

Your problem lies in the following statement:

>>> ' '.join(str(np.array([1,2,3])))
'[ 1   2   3 ]'

You first turn the array into a string format

>>> str(np.array([1,2,3]))
'[1 2 3]'

and then join the elements of the string (individual characters) with spaces in between.


Instead, you need to turn the individual elements of the numpy array into a list of strings, for example by using map.

>>> map(str, np.array([1,2,3]))
['1', '2', '3']

Only then should you join the elements of the resulting list of strings:

>>> ' '.join(map(str, np.array([1,2,3])))
'1 2 3'

The next problem will come from the fact that the numpy array you have is actually two-dimensional:

>>> map(str, np.array([[1,2,3]]))
['[1 2 3]']

This is simple to solve, since you've already turned it into a single row using reshape. So, just apply map to the first row:

>>> ' '.join(map(str, np.array([[1,2,3]])[0]))
'1 2 3'