'Writing a CSV table from column variables?

I am a total beginner in Python, so sorry if it is trivial but I can't solve the problem.

I have 3 lists containing floats.

mouse_x = [-0.01, -0.01, -0.01, -0.01, -0.01, -0.01, -0.01, -0.01, -0.01, -0.01]
mouse_y = [-0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888, -0.14888888888888888]
mouse_time = [1.5307196849607863, 1.581636800954584, 1.6135933389887214, 1.6362467749859206, 1.6675526530016214, 1.6996790579869412, 1.7314749069628306, 1.7635557259782217, 1.7962380870012566, 1.826124977960717]

What I want to do is to combine these three variables so that they are the 3 columns of my CSV file. It should look the following way:

mouse_x, mouse_y, mouse_time
-0.01, -0.14888888888888888, 1.5307196849607863
-0.01, -0.14888888888888888, 1.581636800954584
-0.01, -0.14888888888888888, 1.6135933389887214
...
...

This is what I have tried:

with open('my_file.csv', 'w', newline='') as f:
    thewriter = csv.writer(f)
    thewriter.writerow(['mouse_x', 'mouse_y', 'mouse_time'])
    counter = 0
    for x in mouse_x_list:
        thewriter.writerows(mouse_x_list[counter], mouse_y_list[counter], mouse_time_list[counter])
        counter +=1

This produces the following error:

TypeError: writerows() takes exactly one argument (3 given)



Solution 1:[1]

You need to change writerows to writerow and wrap the three arguments into a list [...]:

thewriter.writerow ( [mouse_x_list[counter], mouse_y_list[counter], mouse_time_list[counter]])

csv.writerows expects a row object, but writerow also accepts simple lists -- as you used earlier to write out the header.

Unrelated, but you can omit the counter by using zip to weave those three lists into one:

for a,b,c in zip(mouse_x_list,mouse_y_list,mouse_time_list):
    thewriter.writerow ( [a,b,c])

Solution 2:[2]

Would you accept to use numpy? I find it to be very straightforward for this kind of applications:

You generate a multidimensional array for which each column is one of your lists:

import numpy as np

arr = np.array([mouse_x, mouse_y, mouse_time])

In this way you can access mouse_x with arr[:, 0], mouse_y with arr[:, 1] and mouse_time with arr[:, 2].

Once you have this data structure, numpy ships a builtin function to save arrays:

np.savetxt('mouse.csv', arr.T, delimiter=',')

Solution 3:[3]

This is one way you can write your CSV file without using NumPy or Pandas:

with open('my_file.csv', 'w') as f:
    thewriter = csv.writer(f)
    thewriter.writerow(['mouse_x', 'mouse_y', 'mouse_time'])
    len_rows = len(mouse_x)
    for counter in range(len_rows):
        thewriter.writerow([mouse_x[counter], mouse_y[counter], mouse_time[counter]])

Notice that you don't need to increment a counter variable yourself here; the for statement in conjunction with range() already sets counter to 0, 1, and so on. Notice that in the for loop, I'm using writerow not writerows.

An arguably more "Pythonic" way to write the CSV file with a for loop would be to do this:

with open('my_file.csv', 'w') as f:
    thewriter = csv.writer(f)
    thewriter.writerow(['mouse_x', 'mouse_y', 'mouse_time'])
    for mx, my, mtime in zip(mouse_x, mouse_y, mouse_time):
        thewriter.writerow([mx, my, mtime])

Now, writerows() takes an iterable of rows, for example, a list or tuple of rows. An iterable, loosely speaking, is what you'd put after the "in" in a for statement. If you had, say, a list of tuples, where tuple i in the list was (mouse_x[i], mouse_y[i], mouse_time[i]), then you could pass that list of tuples to writerows() and be done with it. Alternatively, one could use zip(mouse_x, mouse_y, mouse_time) from the above for loop itself as an argument of writerows():

with open('my_file.csv', 'w') as f:
    thewriter = csv.writer(f)
    thewriter.writerow(['mouse_x', 'mouse_y', 'mouse_time'])
    thewriter.writerows(zip(mouse_x, mouse_y, mouse_time))

Arguably, that's even more Pythonic, for whatever that's worth.

Solution 4:[4]

You can also use pandas to make a dataframe first and than save it as an csv-file:

     import pandas as pd

     df = pd.DataFrame()
     df.insert(0, 'mouse_x', mouse_x)
     df.insert(1, 'mouse_y', mouse_y)
     df.insert(2, 'mouse_time', mouse_time)
     df

output:

        mouse_x mouse_y mouse_time
      0 -0.01   -0.148889   1.530720
      1 -0.01   -0.148889   1.581637
      2 -0.01   -0.148889   1.613593
      3 -0.01   -0.148889   1.636247
      4 -0.01   -0.148889   1.667553
      5 -0.01   -0.148889   1.699679
      6 -0.01   -0.148889   1.731475
      7 -0.01   -0.148889   1.763556
      8 -0.01   -0.148889   1.796238
      9 -0.01   -0.148889   1.826125

save to csv:

     df.to_csv('name_file.csv')

Solution 5:[5]

Numpy is one of the best libraries regarding data stored in arrays. It also includes implementations to save arrays to file directly. Check out how to use it here .

Solution 6:[6]

If you want to use pandas:

import pandas as pd
df=pd.DataFrame([mouse_x,mouse_y,mouse_time])
df.T.to_csv('my_file.csv', index=False, header=['mouse_x','mouse_y','mouse_time'])

Solution 7:[7]

Normally a single binary should only correspond to the specific controller. Because especially Microchip has really wide variaty of microcontrollers. But as you mentioned in your question:

In this instance, the microcontrollers are within the same family but have different size of memory.

You can slightly use the same binary as long as you select the hardware very carefully. I mean if those 3 different models has the same pin mapping but some has less or some has more, then you would select the common corresponding pins for the I/O functions wherever possible. Since those devices are from the same family they must have common IO pins with the same port and pin numbering.

If those similarities including of that the internal registers are enough for the functionality of your system, you can use the same binary for those 3 or more devices as long as you select the right hardware very carefully and none of the functions remain without touching its hardware.

But it is very hard to say the same for the others that are not belong to a series in the same family. In this case you can check the hardware similarities for each functionality of your system. If that micro provides the same hardware, then you can go and firstly give it a try to see whether it will be programmed and then it will funtion in the same way. After making sure enough you can add that model in your usable models list, too.

Hope this give you a helpful idea.

Solution 8:[8]

For two microcontrollers to have compatible binaries, they need to fulfil the following:

  • The CPU cores must have identical Instruction Set Architecture. Be aware that the term "code compatible" by the manufacturer might only mean that two parts have the same ISA and are compatible on the assembly language level, as long as no peripherals or memories are used...
  • In case they have different memory sizes, the part with larger memory must be a superset of the part with smaller memory and they must map memory to the same addresses.
  • All hardware peripherals used must be identical and any peripheral routing registers used must also be identical. Please note that the very same core of the same family but with a different package and pin routing might mean that peripheral routing registers must be set differently.
  • There can be no check of MCU partnumber registers etc inside the firmware, nor can there be any in the flash programming equipment.

In general this means that the MCUs must be of the very same family and the manufacturer must guarantee that they are replaceable.

You can very likely switch between different temperature spec parts of the same model and between automotive/non-automotive qual parts of the same model without changing the code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jongware
Solution 2 rdbisme
Solution 3 jjramsey
Solution 4 Renate van Kempen
Solution 5 Michael Holley
Solution 6
Solution 7 Kozmotronik
Solution 8 Lundin