Writing an ASCII file from a 2D numpy array - python

I have a 2D numpy array. I want to make a ASCII file out of it. Here's the code I am using where a3 is the numpy array
f = open('ASCIIout.asc', 'w')
numpy.savetxt(ASCIIout, a3)
f.write("ncols " + str(ncols) + "\n")
f.write("nrows " + str(nrows) + "\n")
f.write("xllcorner " + str(xllcorner) + "\n")
f.write("yllcorner " + str(yllcorner) + "\n")
f.write("cellsize " + str(cellsize) + "\n")
f.write("NODATA_value " + str(noDATA) + "\n")
f.close()
Now I open it with append option and write the 2D array values:
f_handle = open(ASCIIout, 'a')
numpy.savetxt(f_handle, MyArray, fmt="%.3f")
f_handle.close()
However, I have a couple problems. First, the fmt really does not work I get values like this:
9.999000000000000000e+03
If I JUST use the code below line of code, I get -9999.000 1.345, but then, I haven't attached ncols, nrows, etc to the ASCII file.
numpy.savetxt(f_handle, MyArray, fmt="%.3f")
My data range from 0 to 6. What I really want to get is:
-9999 1.345 -9999 3.21 0.13 -9999
where I do NOT get decimals after -9999 and I do get decimals after real data such as 1.345 I made the ASCII file in R, I am wondering there should be a easy way to do it in Python. Thanks for your help in advance.

If your intention is to have the "stop value" -9999 appear without the decimal point, you can let savetxt() save all the values with the "%.3f" format, and replace the one result you don't want with the one you want:
from StringIO import StringIO
import numpy as np
f = StringIO()
x = np.array(( -9999, 1.345, -9999, 3.21, 0.13, -9999), dtype=float)
np.savetxt(f, x, fmt='%.3f')
f.seek(0)
fs = f.read().replace('-9999.000', '-9999', -1)
f.close()
f = open('ASCIIout.asc', 'w')
f.write("ncols " + str(ncols) + "\n")
f.write("nrows " + str(nrows) + "\n")
f.write("xllcorner " + str(xllcorner) + "\n")
f.write("yllcorner " + str(yllcorner) + "\n")
f.write("cellsize " + str(cellsize) + "\n")
f.write("NODATA_value " + str(noDATA) + "\n")
f.write(fs)
f.close()
If you want all the integer values represented without decimals, .replace('.000', '', -1) would accomplish that.

Related

Writing measurements to a file only writes the first 10 lines

I'm trying to write certain measurements to an output file in python3, but the output file only reflects the first 10 lines
I'm using the following code to write to the file:
f = open("measurements.txt", "w")
for infile in glob.glob("./WAVs/*"):
#do some stuff with the input file
f.write(outfile.removesuffix(".wav") + "\t" + str(oldSIL) + "\t" +
str(oldSPL) + "\t" + str(oldLoud) + "\t" + str(newLoud) + "\t"+
infile.removesuffix(".wav") + "\n")
f.close()
Looking at measurements.txt I find that only the first 10 lines of the expected output have been written.
If I try to print the same lines instead of writing to a file using
print(outfile.removesuffix(".wav") + "\t" + str(oldSIL) + "\t" + str("oldSPL") + "\t" + str(oldLoud) + "\t" + str(newLoud) + "\t"+ infile.removesuffix(".wav") + "\n")
It correctly prints every single line up to the final index. I'm a little lost as to why this might be the case.

double space when exporting to TXT file in python

I have this code that works:
print((tabulate(email_list, showindex=False, tablefmt = 'plain')), file=open(output + '\\' + "np.txt", "w"))
but when I open the file, the email addresses look like this:
b e r o s u n a # g m a i l . c o m
I have tried all the tablefmts and none work, I need it as plain text with no index and no headers left aligned because then I copy them and use it in another process.
Thanks I just changed it completely:
emails = email_list.tolist()
textfile = open(output + '\\' + "np.txt", "w")
for element in emails:
textfile.write(element + "\n")
textfile.close()
os.startfile(output + '\\' + 'np.txt')

Unable to iterate random values in subsequent lines in Python

There are probably many more straightforward ways of achieving my aim here, but as a Python newbie, I'd appreciate it if we could just concentrate on the code I'm using.
I'm attempting to write out a list of commands for a graphics program (G'MIC) and output those to a command prompt (although not directly) using Python 3.6.4 (OS: Windows 10 Pro), I need to write many lines of code but each line has to have different sets of numbers (integers and floats).. for example in the code I'm attempting to use right now the syntax is like this:
gmic v -99 input_.png fx_pastell
0.5,1,0,10,40,633,11,95,1,1,0.291651967558584,0,0,8,150,1,81,1,0,0,0 -o
out_001.png
^ all the variables denote parameters within the particular script (in this case Pastell effect).
The code I wrote relies on the Random module to get certain numbers within a range for each parameter that I want to change.
My stumbling block is to get the script to output DIFFERENT random numbers each time it prints a line. Here is my code (it's awful, I know..):
import random
a = random.randint (3,13)
b = random.randint (1,68)
c = random.randint (1,682)
d = random.randint (2,12)
e = random.randint (1,109)
g = random.randint (1,8)
h = random.uniform (0, 1)
k = random.randint (1,11)
l = random.randint (1,201)
n = random.randint (1,300)
o = random.randint (1,4)
dataFile = open("gmic1.txt", "w")
for line in range(120):
dataFile.write("gmic v -99 input_.png fx_pastell 0.5,1,0" + "," + str(a)
+ "," + str(b) + "," + str(c) + "," +str(d) + "," + str(e) + ",1," + str(g)
+ "," + str(h) + ",0,0," + str(k) + "," + str(l) + ",1," + str(n) + "," +
str(o) +"," + "0,0,0 -o out_%04d.png \n" % line)
dataFile.close()
The output is like this:
gmic v -99 input_.png fx_pastell
0.5,1,0,12,2,521,12,85,1,7,0.04003331068764937,0,0,8,17,1,297,2,0,0,0 -o
out_0000.png
gmic v -99 input_.png fx_pastell
0.5,1,0,12,2,521,12,85,1,7,0.04003331068764937,0,0,8,17,1,297,2,0,0,0 -o
out_0001.png
.. etc...
no errors as such, but not outputting a different set of numbers each time as I'd hoped.
The first input image name variable I can change with Notepad++'s Column Editor, so that takes care of that, I only need to know how to make each line of code differ.
Any help greatly appreciated!
You should call rand function on every iteration
from random import randint, uniform
dataFile = open("gmic1.txt", "w")
for line in range(120):
dataFile.write("gmic v -99 input_.png fx_pastell 0.5,1,0"
+ "," + str(randint(3, 13))
+ "," + str(randint(1, 68))
+ "," + str(randint(1, 682))
+ "," + str(randint(2, 12))
+ "," + str(randint(1, 109))
+ ",1," + str(randint(1, 8))
+ "," + str(uniform(0, 1))
+ ",0,0," + str(randint(1, 11))
+ "," + str(randint(1, 201))
+ ",1," + str(randint(1, 300))
+ "," + str(randint(1, 4))
+ "," + "0,0,0 -o out_%04d.png \n" % line)
dataFile.close()

Leading/prefix 0s in out of for loop

I am writing a four loop in my program that writes data to a file. I'm wanting for the output to be formatted as follows
frame001 + K.1
frame002 + K.2
...
frame099 + K.99
frame100 + K.100
So far I am doing
for f in range(1, 100):
file.write('frame' + str(f) + ' + K.' + str(f) + '\n')
I have no problem having the K part come out correctly as K.1-K.100, but I don't know how to have prefix zeros/have it output also frame00F to frameFFF with the appropriate amount of preceding zeros.
Using str.format:
>>> 'frame{0:03d} + K.{0}\n'.format(1)
'frame001 + K.1\n'
>>> 'frame{0:03d} + K.{0}\n'.format(100)
'frame100 + K.100\n'
BTW, range(1, 100) will not yield 100. If you want 100 to be included, that should be range(1, 101).
If you are using old version of Python (Python 2.5-), use % operator (String formatting operator) instead (need to specify multiple argument unlike str.format)
>>> 'frame%03d + K.%d\n' % (1, 1)
'frame001 + K.1\n'
>>> 'frame%03d + K.%d\n' % (100, 100)
'frame100 + K.100\n'
If you don't want to repeat arguments, you can pass mapping instead with slightly different format specifier:
>>> 'frame%(i)03d + K.%(i)d\n' % {'i': 1}
'frame001 + K.1\n'

printing an array in python columnwise

I am trying to add an array like this given below
# N Mn Fe x x2
3.94870000e+01 -1.22950000e-07 -1.65130000e-05 6.40000000e-01 0.00000000e+00
3.95040000e+01 -9.38580000e-07 -1.63070000e-05 6.41000000e-01 0.00000000e+00
3.95130000e+01 -1.67100000e-06 -1.59280000e-05 6.42000000e-01 0.00000000e+00
3.95230000e+01 -2.29230000e-06 -1.53800000e-05 6.43000000e-01 0.00000000e+00
The code I have managed to write do add the column Mn and Fe, but not yet managed to write it in column as:
# N Mn Fe Res
The code that I have written is:
#!/usr/bin/env python3
# encoding: utf-8
import numpy as np
inp = "ec.dat"
out = "ec2.dat"
N, Mn, Fe, x, x2 = np.loadtxt(inp, unpack=True)
res = Mn+Fe
print(N, res)
# with open("ec2.dat", 'a') as outfile:
Will anyone kindly help me in writing the table properly?
Regards,
EDIT #Paul, Thanks. The complete code is now:
#!/usr/bin/env python3
# encoding: utf-8
import numpy as np
inp = "ec.dat"
out = "ec2.dat"
N, Mn, Fe, x, x2 = np.loadtxt(inp, unpack=True)
res = Mn+Fe
with open("ec2.dat", "w") as of:
for n, mn, fe, res in zip(N, Mn, Fe, res):
s = "%e %e\n" % (n, res)
of.write(s)
Rather than put the answer together, I will show you individual parts so you can work through this yourself.
To iterate over multiple numpy arrays simultaneously, you could do the following:
for n, mn, fe, result in zip(N, Mn, Fe, res):
print "" + str(n) + " " + str(mn) +" " + str(fe) + " " + str(result)
However, to perform the desired formatting, you should use string specifiers: https://docs.python.org/2/library/string.html#format-specification-mini-language
One example would be something like
v = 1000.526
s = "%e %e\n" % (10.25, v)
print s
writing to a file is as simple as doing:
s = "Here is a line I will write to my file\n"
with open("ec2.dat", 'a') as outfile:
outfile.write(s)
Linking these things together you should be able to print your desired output to the screen or a file.

Categories