I've a little problem here. I need to read a txt file and store it into a list, I'm already doing that... but the problem is that I need to manipulate some columns like multiplying then by 30 and so forth so on. (I'm still learning python) (Its python 3.4)
The test.txt file:
Abacate;Para;PA;-1.1166667;-49.65
Abacate;Amazonas;AM;-3.9463889;-62.9038889
The code:
def readFile():
with open('test.txt') as f:
reader = csv.reader(f,delimiter=";")
#reader.next()
for row in reader:
for (i,v) in enumerate(row):
columns[i].append(v)
But, when I try to use
for i in range(0,len(columns[3])):
listTest.append(columns[3][i]*3)
The result is:
['-1.1166667-1.1166667-1.1166667']
['-1.1166667-1.1166667-1.1166667', '-3.9463889-3.9463889-3.9463889']
Expected:
['-3.3500001','-11.8391667']
Is there a better way to do this?
Python is reading the numbers as strings, so when you do the *3 it thinks "Ah! Matt wants me to put the the string three times in a row!"
If you just convert it to a float first, it'll be fine:
for i in range(0,len(columns[3])):
listTest.append(float(columns[3][i])*3)
You need to parse the columns[3][i] into float like
listTest.append(float(columns[3][i])*3)
Because
'any_string'*3
>>any_stringany_stringany_string
100*3
>>300
import csv
def readFile(infilepath):
answer = []
with open(infilepath) as infile:
for *_head, a, _b in csv.reader(infile, delimiter';'):
answer.append(float(a) * 3)
return answer
Related
I'm trying to figure out if there is a way to read a table like this:
x1 y1 z1
x2 y2 z2
.. .. ..
xn yn zn
And then have my code print a text file that looks like this:
\object{x1}
\ra{y1}
\dec{z1}
\object{x2}
\ra{y2}
\dec{z2}
\object{..}
\ra{..}
\dec{..}
\object{xn}
\ra{yn}
\dec{zn}
Thus far, I have a code that reads in these arrays just fine, but I do not know how to save them to a text file that's anything other than exactly what was read in. Is there a way I can have each of these lines printed in some customized format, like above?
I've tried
np.savetxt('data.txt',zip(x,y,z),fmt='(messing with formatting options here)')
but I've had no luck and I'm not sure if savetxt is even the right route. Thanks very much in advance for any help you can provide!
if you have an array arr and want your output in a file, you can try:
arr = [['x1','y1','z1'],
['x2','y2','z2'],
['x3','y3','z3']]
with open('latex.txt', 'a') as myfile:
[myfile.write('\object{'+row[0]+'}\n\\ra{'+row[1]+'}\n\dec{'+row[2]+'}\n\n') for row in arr]
This should do the job:
import numpy as np
txt = np.genfromtxt('input.txt', dtype='str')
# python >= 3.6
with open('outfile.txt', 'w') as file:
file.write("\n".join(
[f'\\object{{{row[0]}}}\n'
f'\\ra{{{row[1]}}}\n'
f'\\dec{{{row[2]}}}\n'
'\\color{red}\n' # static line
for row in txt]
))
# python < 3.6
with open('outfile.txt', 'w') as file:
file.write("\n".join(
['\\object{{{row[0]}}}\n'
'\\ra{{{row[1]}}}\n'
'\\dec{{{row[2]}}}\n'
'\\color{{red}}\n'.format(row=row) # static line
for row in txt]
))
You need to split the reading and writing processes. A solution involving the use of the module csv, to read comma separated values from a file (in this case, not a comma but a space).
Here data.txt is the file with the table, out.txt the file with the format you want.
import csv
with open('data.txt') as rr:
reader = csv.reader(rr, delimiter=' ')
with open('out.txt', 'w') as oo:
for line in reader:
oo.write(f"\\object{{{line[0]}}}\n")
oo.write(f"\\ra{{{line[1]}}}\n")
oo.write(f"\\dec{{{line[2]}}}\n\n")
Notice the triple curly braces in the formatted string literals two braces to print a brace, one to print the variable value.
If your python version is < 3.6, use instead:
oo.write("\\object{{{}}}\n".format(line[0]))
oo.write("\\ra{{{}}}\n".format(line[1]))
oo.write("\\dec{{{}}}\n\n".format(line[2]))
EDIT after comment
To add extra lines each block, simply write them with an extra call to oo.write inside the for loop. For example:
oo.write(f"\\object{{{line[0]}}}\n")
oo.write(f"\\ra{{{line[1]}}}\n")
oo.write(f"\\dec{{{line[2]}}}\n")
oo.write("\color{red}\n\n") #no need to use format here, one curly bracket is enough
Last line does not depend on line, so will be the same each iteration of the for loop.
I'm trying to write data from a list of lists to a csv file. This is a simplified version of what I have
class Point(object):
def __init__(self, weight, height):
self.weight = weight
self.height = height
def get_BMI(self):
return (self.weight * self.height) / 42 # this is not how you calculate BMI but let's say
myList = [[Point(30, 183)],[Point(63, 153)]]
Because of the way the data is set up, I store the points in a nested loop. If I wanted to access the first point object’s BMI, I would type
myList[0][0].get_BMI()
I want to write each point's BMI to a CSV (delimited by a comma). How do I do that?
Here's how I thought but it isn't exactly straight forward:
import csv
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(myList)
It doesn't return any error however it doesn't actually create the CSV file either. Also I want to write the values in myList[i][j].get_BMI() to file. I don't have a problem with permissions because I use Spyder (python IDE) as root. Right now I'm just running the script through the Spyder console but it should still work and output the CSV file.
writerows expects a list of list of strings or numbers. You should start by creating a list with the BMI values so that they can get written into your csv file:
import csv
BMIs = [[point.get_BMI() for point in points] for points in myList]
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(BMIs)
You can do this with writerows, as it expects a list of rows - each row should be formatted as per the dialect parameter to csv.writer, which can be ignored in this case without fear of any backfiring.
So writerows can take a structure that looks like myList. The problem is that you need to access all the points and grab their BMIs (this can be done in a list comprehension)
To illustrate how writerows can be used (and to add a number to each point, so that all your rows don't have just one entry (which would be frustrating), I added the call to enumerate.
Therefore, you no longer need complex loops or any such. Enjoy:
myList = [[Point(30, 183)],[Point(63, 153)]]
with open('output.csv', 'w') as outfile:
writer = csv.writer(outfile)
writer.writerows(enumerate(p.get_BMI() for p in itertools.chain.from_iterable(myList)))
There are three issues:
The nested lists must be flattened. To accomplish this, use itertools.chain.from_iterable.
The row data for the CSV must be customized. To accomplish this, use list comprehensions.
output.csv is not being created. I suspect that the output.csv is being created but being placed in an unexpected location. You could try hardcoding a full path for testing to see if this is the case.
Here is code that demonstrates #1 and #2:
import csv
from itertools import chain
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
flattenedList = chain.from_iterable(myList)
writer.writerows((pt.weight, pt.height, pt.get_BMI()) for pt in flattenedList)
myList = [[Point(30, 183)],[Point(63, 153)]]
with open('output.csv', 'w') as outfile:
writer = csv.writer(outfile,delimiter=',')
for i in myList:
writer.writerow([i])
I have list like the one below,
lista=["a","b","c","\n","d","e","f","\n","g","h","i","\n"]
Can some one please advise how I make csv module to write this so that every "\n" in the list is counted as a line break? To make it simpler the csv should look like this,
a,b,c
d,e,f
g,h,i
Please let me know if the question is not clear, I will make changes as required.
import csv
import sys
def rows(lst):
it = iter(lst)
while True:
row = list(iter(it.next, '\n')) # it.__next__ in Python 3.x
if not row:
break
yield row
lista = ["a","b","c","\n","d","e","f","\n","g","h","i","\n"]
writer = csv.writer(sys.stdout) # Replace sys.stdout with file object
writer.writerows(rows(lista))
You don't really need the CSV module:
for s in ','.join(lista).split('\n'):
print(s.strip(','), '\n')
This gives:
a,b,c
d,e,f
g,h,i
I am a second year EE student.
I just started learning python for my project.
I intend to parse a csv file with a format like
3520005,"Toronto (Ont.)",C ,F,2503281,2481494,F,F,0.9,1040597,979330,630.1763,3972.4,1
2466023,"Montréal (Que.)",V ,F,1620693,1583590,T,F,2.3,787060,743204,365.1303,4438.7,2
5915022,"Vancouver (B.C.)",CY ,F,578041,545671,F,F,5.9,273804,253212,114.7133,5039.0,8
3519038,"Richmond Hill (Ont.)",T ,F,162704,132030,F,F,23.2,53028,51000,100.8917,1612.7,28
into a text file like the following
Toronto 2503281
Montreal 1620693
Vancouver 578041
I am extracting the 1st and 5th column and save it into a text file.
This is what i have so far.
import csv
file = open('raw.csv')
reader = csv.reader(file)
f = open('NicelyDone.text','w')
for line in reader:
f.write("%s %s"%line[1],%line[5])
This is not working for me, I was able to extract the data from the csv file as line[1],line[5]. (I am able to print it out)
But I dont know how to write it to a .text file in the format i wanted.
Also, I have to process the first column eg, "Toronto (Ont.)" into "Toronto".
I am familiar with the function find(), I assume that i could extract Toronto out of Toronto(Ont.) using "(" as the stopping character,
but based on my research , I have no idea how to use it and ask it to return me the string(Toronto).
Here is my question:
What is the data format for line[1]?
If it is string how come f.write() does not work?
If it is not string, how do i convert it to a string?
How do i extract the word Toronto out of Toronto(Ont) into a string form using find() or other methods.
My thinking is that I could add those 2 string together like c = a+ ' ' + b, that would give me the format i wanted.
So i can use f.write() to write into a file :)
Sorry if my questions sounds too easy or stupid.
Thanks ahead
Zhen
All data read you get from csv.reader are strings.
There is a variety of solutions to this, but the simplest would be to split on ( and strip away any whitespace:
>>> a = 'Toronto (Ont.)'
>>> b = a.split('(')
>>> b
Out[16]: ['Toronto ', 'Ont.)']
>>> c = b[0]
>>> c
Out[18]: 'Toronto '
>>> c.strip()
Out[19]: 'Toronto'
or in one line:
>>> print 'Toronto (Ont.)'.split('(')[0].strip()
Another option would have been to use regular expression (the re module).
The specific problem in your code lies here:
f.write("%s %s"%line[1],%line[5])
Using the % syntax to format your string, you have to provide either a single value, or an iterable. In your case this should be:
f.write("%s %s" % (line[1], line[5]))
Another way to do the exact same thing, is to use the format method.
f.write('{} {}'.format(line[1], line[5]))
This is a flexible way of formating strings, and I recommend that you read about in the docs.
Regarding your code, there is a couple of things you should consider.
Always remember to close your file handlers. If you use with open(...) as fp, this is taken care of for you.
with open('myfile.txt') as ifile:
# Do stuff
# The file is closed here
Don't use reserved words as your variable name. file is such a thing, and by using it as something else (shadowing it), you may cause problems later on in your code.
To write your data, you can use csv.writer:
with open('myfile.txt', 'wb') as ofile:
writer = csv.writer(ofile)
writer.writerow(['my', 'data'])
From Python 2.6 and above, you can combine multiple with statements in one statement:
with open('raw.csv') as ifile, open('NicelyDone.text','w') as ofile:
reader = csv.reader(ifile)
writer = csv.writer(ofile)
Combining this knowledge, your script can be rewritten to something like:
import csv
with open('raw.csv') as ifile, open('NicelyDone.text', 'wb') as ofile:
reader = csv.reader(ifile)
writer = csv.writer(ofile, delimiter=' ')
for row in reader:
city, num = row[1].split('(')[0].strip(), row[5]
writer.writerow([city, num])
I don't recall csv that well, so I don't know if it's a string or not. What error are you getting? In any case, assuming it is a string, your line should be:
f.write("%s %s " % (line[1], line[5]))
In other words, you need a set of parentheses. Also, you should have a trailing space in your string.
A somewhat hackish but concise way to do this is: line[1].split("(")[0]
This will create a list that splits on the ( symbol, and then you extract the first element.
I want to write data that I have to create a histogram into a csv file. I have my 'bins' list and I have my 'frequencies' list. Can someone give me some help to write them into a csv in their respective columns?
ie bins in the first column and frequency in the second column
The original Python 2 answer
This example uses izip (instead of zip) to avoid creating a new list and having to keep it in the memory. It also makes use of Python's built in csv module, which ensures proper escaping. As an added bonus it also avoids using any loops, so the code is short and concise.
import csv
from itertools import izip
with open('some.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerows(izip(bins, frequencies))
The code adapted for Python 3
In Python 3, you don't need izip anymore—the builtin zip now does what izip used to do. You also don't need to open the file in binary mode:
import csv
with open('some.csv', 'w') as f:
writer = csv.writer(f)
writer.writerows(zip(bins, frequencies))
you should use zip()
http://docs.python.org/2/library/functions.html#zip
something like :
f=open(my_filename,'w')
for i,j in zip(bins,frequencies):
f.write(str(i)+","+str(j))
f.close()
Hm, am I missing something? This sounds pretty straightforward:
bins = [ 1,2,3,4,5 ]
freq = [ 9,8,7,6,5 ]
f = open("test.csv", "w")
for i in xrange(len(bins)):
f.write("{} {}\n".format(bins[i], freq[i]))
f.close()