How to write several commas in a CSV file in python - python

I'm converting a .txt file with annotations into another annotation format in a .csv file. The annotation format is as follows: filepath,x1,y1,x2,y2,classname. For pictures which haven't an instance of any class in them, annotation is like this: filepath,,,,,.
The problem is, that the .writerrow method of the csv.writer class doesn't write more than one comma after another.
My code is like this:
with open(annotation_file, 'r') as file:
lines = file.readlines()
splitted_lines = [line.split(' ') for line in lines]
with open(out_file, 'w', newline = '') as out:
csv_writer = csv.writer(out,delimiter= ';' )
for l in splitted_lines:
if len(l) == 1:
# indicate empty images
csv_writer.writerow([l[0] + ',,,,,'])
l is a list that contains a single string, so by l[0] + ',,,,,' I want to concatenate l with five commas.
Thank you in advance

set missing values as empty strings and fill the list
with open(annotation_file, 'r') as file:
lines = file.readlines()
splitted_lines = [line.split(' ') for line in lines]
with open(out_file, 'w', newline='') as out:
csv_writer = csv.writer(out, delimiter=';')
for l in splitted_lines:
if len(l) == 1:
# indicate empty images
csv_writer.writerow(l + ['' for _ in range(5)])
else:
csv_writer.writerow(l)
Given sample data:
data = [
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1],
]
it outputs:
1;2;3;4;5;6
1;2;3;4;5;6
1;2;3;4;5;6
1;;;;;
which is inline with what you want

I discovered my problem, l is a string which contained a '\n' at the end. Because of this the writer wasn't able to write the five commas to the string. I changed the code like displayed below what fixed the problem.
with open(annotation_file, 'r') as file:
lines = file.readlines()
splitted_lines = [line.split(' ') for line in lines]
with open(out_file, 'w', newline = '') as out:
csv_writer = csv.writer(out,delimiter= ';' )
for l in splitted_lines:
if len(l) == 1:
# indicate empty images
l[0] = l[0].replace('\n', '')
csv_writer.writerow([l[0] + ',,,,,'])
else:
csv_writer.writerow(['something else'])
Thanks anyway #DelphiX

Related

How to add a list with a list and integers into a csv?

I am trying to put the following into a csv. Here is my code
import csv
data = [[1, 2, 3], 4, 5]
with open('test.csv', 'w') as f:
writer = csv.writer(f)
writer.writerows(data)
I am getting the following error:
_csv.Error: iterable expected, not int
When writing writer.writerow, then the code works but gives [1, 2, 3], 4 and 5 as the columns.
I want the columns to be 1, 2, 3, 4, 5
Any help on how I can do it?
writerow isn't equivalent to writerows
>>> some_data = [[1,2,3],[4,5,6],[7,8,9]]
>>> writer.writerows(some_data)
>
1,2,3
4,5,6
7,8,9
>>> write.writerow(some_data)
>"[1, 2, 3]","[4, 5, 6]","[7, 8, 9]"
Try:
import csv
headers = [1,2,3,4,5]
some_data = ['Foo','Bar','Baz','Qux','Zoo']
more_data = [['d1','d2','d3'],['d4','d5','d6']]
with open('test.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(headers) # Takes an iterable of cells
writer.writerow(some_data)
writer.writerows(more_data) # Takes an iterable of iterables
And you'll get:
1,2,3,4,5
Foo,Bar,Baz,Qux,Zoo
d1,d2,d3
d4,d5,d6
import csv
data = [[1, 2, 3,4], 5,6]
print_data = []
with open('test.csv', 'w') as f:
writer = csv.writer(f)
# Following code flattens the list within a list,
# uses temporary 'print_data' to store values for printing to csv
for counter in range(len(data)):
if isinstance(data[counter], list)==1 :
print ('list found')
for val in data[counter]:
print_data.append(val)
else:
print_data.append(data[counter])
writer.writerow(print_data)

How to extract a number of a txt and pass to an array

I have a .txt with 10 lines like this:
[-3 -4 -5 -6 -7], 0
I want to extract the number between [...] and pass them to an array of integers, i'm reading the .txt like this:
import sys
with open(sys.argv[1], 'r') as f:
contents = f.read()
print(contents)
I need to divide the part before the coma?
There is any function to do this?
What should i do?
This should do it:
import sys
with open(sys.argv[1], 'r') as f:
contents = f.read()
arrays = []
for line in contents.split('\n'):
array_string = line.split(',')[0]
array = [int(i) for i in array_string[1:-1].split()]
arrays.append(array)
This will return, based on your example:
arrays
[[-3, -4, -5, -6, -7]]
Try something like that, but it's a bit meaty:
with open('your_file.txt', 'r') as f:
new_list = [item.split(',')[0][1:-1].split() for item in f.readlines()]
print(new_list)
my fault, hasn't seen that file will be provided like argument, then
#!/bin/python3
from sys import argv
with open(argv[1], 'r') as f:
new_list = [item.split(',')[0][1:-1].split() for item in f.readlines()]
print(new_list)
by the way, regex solution, also seems good:
with open(argv[1], 'r') as f:
new_list = [re.findall('-?\d+', item.split(',')[0]) for item in f.readlines()]
print(new_list)
test = "[-3 -4 -5 -6 -7], 0"
# split on the ','
test = test.split(",")
# remove the '[' and ']' and split on the whitespace
res = test[0].lstrip("[").rstrip("]").split(" ")
# add the standalone value to the the list?
res.append(test[1])
# cast values to int
res = [int(x) for x in res]
# print out the result
print(res)
result:
[-3, -4, -5, -6, -7, 0]
You can read the data to a list with a single line, as follows.
import sys
data = [ [ int(field) for field in row.split(sep=",")[0][1:-1].split() ] for row in open(sys.argv[1])]
You will get e.g.:
[[-3, -4, -5, -6, -7]]
The read mode is default for open, so you can omit it.
You go through the lines of the file.
For each row, you split the row by the "," separator.
The left part you can split simply to a list.
This list contains string fields which you can convert to int.
try this :
import sys
import re
with open(sys.argv[1], 'r') as f:
contents = f.read()
arrays = []
for line in contents.split('\n'):
string = line.split(',')[0]
arrays.append(re.findall("[+-]?\d+(?:\.\d+)?",string))

how to export two columns to csv in python

I am not familiar with how to export the list to the csv in python. Here is code for one list:
import csv
X = ([1,2,3],[7,8,9])
Y = ([4,5,6],[3,4,5])
for x in range(0,2,1):
csvfile = "C:/Temp/aaa.csv"
with open(csvfile, "w") as output:
writer = csv.writer(output, lineterminator='\n')
for val in x[0]:
writer.writerow([val])
And I want to the result:
Then how to modify the code(the main problem is how to change the column?)
To output multiple columns you can use zip() like:
Code:
import csv
x0 = [1, 2, 3]
y0 = [4, 5, 6]
x2 = [7, 8, 9]
y2 = [3, 4, 5]
csvfile = "aaa.csv"
with open(csvfile, "w") as output:
writer = csv.writer(output, lineterminator='\n')
writer.writerow(['x=0', None, None, 'x=2'])
writer.writerow(['x', 'y', None, 'x', 'y'])
for val in zip(x0, y0, [None] * len(x0), x2, y2):
writer.writerow(val)
Results:
x=0,,,x=2
x,y,,x,y
1,4,,7,3
2,5,,8,4
3,6,,9,5
You could try:
with open('file.csv') as fin:
reader = csv.reader(fin)
[fout.write(r[0],r[1]) for r in reader]
If you need further help, leave a comment.
When dealing with csv files you should really just use Pandas. Put your header and data into a dataframe, and then use the .to_csv method on that dataframe. Csv can get tricky when you have strings that contain commas, etc...
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html

How to start slicing from the second line?

My current code reads the 1st line, then 3rd, 5th, 7th and so on and adds it to a list.
I want it to read the 2nd, 4th, 6th lines ... and add it to another list.
with open(path) as f:
content = f.readlines()
content = [x.strip() for x in content[::2]]
You need to add a start to your slice of 1, e.g. content[1::2]:
with open(path) as f:
content = f.readlines()
content = [x.strip() for x in content[1::2]]
A better alternative would be to use itertools.islice() to do this, as follows:
from itertools import islice
with open(path) as f_input:
content = [line.strip() for line in islice(f_input, 1, None, 2)]
You need to start slicing by skipping the first item; here is an example:
>>> list(i)
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> list(i[1::2])
[1, 3, 5, 7, 9]
In your code:
content = [x.strip() for x in content[1::2]]
your code should be like that
meaning that the slice starts from 1 to the end of the list with a step of two.
with open(path) as f:
content = f.readlines()
content = [x.strip() for x in content[1::2]]
from itertools import islice
with open(path) as f_input:
content = [line.strip() for line in islice(f_input, 1, None, 2)]

write zip array vertical in csv

is there ways to display zipped text vertically in csv ?? I tried many difference type of \n ',' but still can't get the array to be vertical
if __name__ == '__main__': #start of program
master = Tk()
newDirRH = "C:/VSMPlots"
FileName = "J123"
TypeName = "1234"
Field = [1,2,3,4,5,6,7,8,9,10]
Court = [5,4,1,2,3,4,5,1,2,3]
for field, court in zip(Field, Court):
stringText = ','.join((str(FileName), str(TypeName), str(Field), str(Court)))
newfile = newDirRH + "/Try1.csv"
text_file = open(newfile, "w")
x = stringText
text_file.write(x)
text_file.close()
print "Done"
This is the method i am looking for for your Code i can't seem to add new columns as all the column will repeat 10x
You are not writing CSV data. You are writing Python string representations of lists. You are writing the whole Field and Court lists each iteration of your loop, instead of writing field and court, and Excel sees the comma in the Python string representation:
J123,1234,[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],[5, 4, 1, 2, 3, 4, 5, 1, 2, 3]
J123,1234,[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],[5, 4, 1, 2, 3, 4, 5, 1, 2, 3]
etc.
while you wanted to write:
J123,1234,1,5
J123,1234,2,4
etc.
Use the csv module to produce CSV files:
import csv
with open(newfile, "wb") as csvfile:
writer = csv.writer(csvfile)
for field, court in zip(Field, Court):
writer.writerow([FileName, TypeName, field, court])
Note the with statement; it takes care of closing the open file object for you. The csv module also makes sure everything is converted to strings.
If you want to write something only on the first row, keep a counter with your items; enumerate() makes that easy:
with open(newfile, "wb") as csvfile:
writer = csv.writer(csvfile)
# row of headers
writer.writerow(['FileName', 'TypeName', 'field', 'court'])
for i, (field, court) in enumerate(zip(Field, Court)):
row = [[FileName, TypeName] if i == 0 else ['', '']
writer.writerow(row + [field, court])

Categories