I'm reading a sequence of files and writing them and their parameters in lists, then I want to create a csv which looks like this:
File1 | parameterA1 | parameterA2 | |
---|---|---|---|
File2 | parameterP1 | parameterP2 | parameterP3 |
What I get with my code:
file1 parameterA parameterA2 |
---|
file2 parameterP1 parameterP2 parameterP3 |
How can I get each parameter in its own cell? Any help appreciated. What's interesting, if I run the code with just 1 file - parameters put in separate cells.
import csv
files = ['f1', 'f2']
params_a = ['a1', 'a2']
params_p = ['p1', 'p2', 'p3']
with open ('csv.csv', 'a') as csvfile:
csvwriter = csv.writer(csvfile, delimiter = ',')
for file in files:
csvfile.write('\n%s\t' % (file) )
for parameter_a in params_a:
csvfile.write('%s\t' % (parameter_a))
for parameter_p in params_p:
csvfile.write('%s\t' % (parameter_p))
I tried playing with delemeter, other arguments and line endings but it got worse. Not sure what breaks the 'style' for multiple writing operations.
UPD: updated the table to match the code sample
CodePudding user response:
To write the CSV from your question you can use next example:
import csv
files = ['f1', 'f2']
params_a = ['a1', 'a2']
params_p = ['p1', 'p2', 'p3']
with open('data.csv', 'w') as f_out:
writer = csv.writer(f_out)
# write header
writer.writerow(['Column A', 'Column B', 'Column C'])
# write rows
for f, p1, p2 in zip(files, params_a, params_p):
writer.writerow([f, p1, p2])
This writes data.csv
with following content:
Column A,Column B,Column C
f1,a1,p1
f2,a2,p2
CodePudding user response:
The most straightforward answer based on the code you provided is this:
files = ["f1", "f2"]
params_a = ["a1", "a2"]
params_p = ["p1", "p2", "p3"]
with open("output_manual.csv", "a", newline="") as csvfile:
csvwriter = csv.writer(csvfile)
row = [files[0]] params_a
csvwriter.writerow(row)
row = [files[1]] params_p
csvwriter.writerow(row)
That outputs:
f1,a1,a2
f2,p1,p2,p3
That params_a belongs to file "f1", and params_p to "f2", seems to be special knowledge you need to manually code.
If your data actually looked like this:
files = [
"f1",
"f2",
]
params = [
["a1", "a2"],
["p1", "p2", "p3"],
]
Then you can do something like this:
with open("output_mine.csv", "w", newline="") as f_out:
writer = csv.writer(f_out)
for i, file in enumerate(files):
row = [file] params[i]
writer.writerow(row)
You can also dynmaically size a header, if you like:
max_param_len = 0
for param in params:
if len(param) > max_param_len:
max_param_len = len(param)
header = ["File"]
for i in range(max_param_len):
header = [f"Param_{i 1}"]
and then insert it:
...
writer = csv.writer(f_out)
writer.writerow(header)
...
That outputs:
File,Param_1,Param_2,Param_3
f1,a1,a2
f2,p1,p2,p3
Your data could also look like this and something similar will work:
file_param_map = {
"f1": ["a1", "a2"],
"f2": ["p1", "p2", "p3"],
}
CodePudding user response:
import csv
with open('params_test', 'w') as csv_file:
files = ['f1', 'f2']
params_a = ['a1', 'a2']
params_p = ['p1', 'p2', 'p3']
# Find the max number of columns needed.
col_max = max(len(params_a), len(params_p))
c_writer = csv.writer(csv_file)
for p in [params_a, params_p]:
# If number of columns is < the max number pad with empty strings
if len(p) < col_max:
for l in range(col_max - len(p)):
p.append('')
# Add the file name to start of params* list. Then write out row.
params_a.insert(0, files[0])
c_writer.writerow(params_a)
params_p.insert(0, files[1])
c_writer.writerow(params_p)
cat params_test
f1,a1,a2,
f2,p1,p2,p3