0

I really need some help.

We collect engine data which comes in a compressed file with filename like data_XXXXXX.csv.gz. Compressed these files are about 50KB, decompressed they go up to about 3,5MB. They contain about 7000 lines of data where each line has about 240 values, seperated by ";".

A few lines of data looks like this:

2015-04-04 03:03:21;DIG. Engine 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:21;ANA. Engine 1;1609;0;0;1224;1601;0;0;0;0;260;0;0;0;0;0;0;0;84;0;921;22;28;310;390;364;357;0;289;293;289;289;298;305;298;302;306;297;320;297;314;303;308;301;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;424;372;24;2;0;4;0;2;8;740;432;444;2320;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2800;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;4;3;2;2;1;2;1;27;380;0;0;0;42717;14;0;0;0;0;0;0;0;0;0;0;5998;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;DIG. Engine 2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;ANA. Engine 2;1602;0;0;1012;1602;0;0;0;0;240;0;0;0;0;0;0;0;84;0;933;22;28;283;370;324;332;0;283;293;274;280;298;278;285;285;266;292;289;303;262;275;270;285;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;428;372;26;3;0;4;0;4;22;720;452;444;2288;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2825;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;4;3;2;2;3;2;1;27;384;0;0;0;44114;14;0;0;0;0;0;0;0;0;0;0;6002;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;DIG. Engine 3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;ANA. Engine 3;1516;0;0;324;0;0;0;0;0;170;0;0;0;0;0;0;0;81;24;0;0;11;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;572;492;40;0;0;0;0;125;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2750;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;414;182;63;82;505;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;4;8;3;4;1;3;1;12;704;0;0;0;22382;4;0;0;0;0;0;0;0;0;0;0;8972;0;0;0;0;0;0;0;0;0;0;0;46679;12;0;0;0;0;0;0;0;0;0;0;0;0;0

Via a Python script I managed to decompress and edit the file to add a column between the first and second, using something like:

try:
    for row in reader:
    row.insert(1,InstallationName)
    newdat.append(row)
except:#encountered a .gz file which was unable to be altered. let's prevent that! 
    f.close()
    outfile.close()
else:
    writer.writerows(newdat)
    f.close()
    outfile.close()

When this is complete the file is imported in an MSSQL database using bulkimport, so we really need a clean .csv file!

An example of the output would be:

2015-04-04 03:03:21;SOMETEXT;DIG. Engine 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:21;SOMETEXT;ANA. Engine 1;1609;0;0;1224;1601;0;0;0;0;260;0;0;0;0;0;0;0;84;0;921;22;28;310;390;364;357;0;289;293;289;289;298;305;298;302;306;297;320;297;314;303;308;301;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;424;372;24;2;0;4;0;2;8;740;432;444;2320;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2800;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;4;3;2;2;1;2;1;27;361;0;0;0;42717;14;0;0;0;0;0;0;0;0;0;0;5998;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;SOMETEXT;DIG. Engine 2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;SOMETEXT;ANA. Engine 2;1602;0;0;1012;1602;0;0;0;0;240;0;0;0;0;0;0;0;84;0;933;22;28;283;370;324;332;0;283;293;274;280;298;278;285;285;266;292;289;303;262;275;270;285;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;428;372;26;3;0;4;0;4;22;720;452;444;2288;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2825;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;4;3;2;2;3;2;1;27;365;0;0;0;44114;14;0;0;0;0;0;0;0;0;0;0;6002;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;SOMETEXT;DIG. Engine 3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
2015-04-04 03:03:22;SOMETEXT;ANA. Engine 3;1516;0;0;324;0;0;0;0;0;170;0;0;0;0;0;0;0;81;24;0;0;11;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;572;492;40;0;0;0;0;125;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2750;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;414;182;63;82;505;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;4;8;3;4;1;3;1;12;332;0;0;0;22382;4;0;0;0;0;0;0;0;0;0;0;8972;0;0;0;0;0;0;0;0;0;0;0;46679;12;0;0;0;0;0;0;0;0;0;0;0;0;0

Now this works, it alters the decompressed .csv file just the way I would like it to. But there's one downside. The size of the file in combination with the script is giving me headaches because when it runs on multiple files the CPU usage skyrockets and the server can't keep up anymore.

Now I have been trying to speed up the process using an enumerate expression but I just can't get the output I want. Where the row-by-row way would take up to 10 seconds per file the enumerate way gives me 'a' file in about 3 seconds. I say 'a' file because I can't get the output to match the input (with added column).

Lastly the system/software we are using is based on Python 2.X (actually it's Jython).

I know this is the place to be to get this working, if you have any questions please do ask!

Oliver W.
  • 13,169
  • 3
  • 37
  • 50

1 Answers1

0

You'll get a performance boost in this case by not using the csv module, as it splits a whole lot more than necessary. Instead, consider using the much simpler split method, specifying the optional argument to only split one time by the semicolon delimiting your columns.

with open(csvfile) as f, open(outputfile, 'w') as out:
    for line in f:
        tmp = line.split(';', 1) # splits only once
        tmp.insert(1, extra_string)
        out.write(';'.join(tmp))

I haven't checked if jython supports the double context-manager (it supports the single type for sure), if not, split it over several lines.

At the same time, this will prevent the memory from getting overly full (a potential risk with the way you handled newdat.append if the files would've been much larger than 3.5MB) and it will use the default buffering mechanisms of f.write. Of course, you're not forced to use it: if you find that it works better for you to fill up the memory and then call writelines then use that (although the buffering mechanism is always specified by the call to open, so I wouldn't expect to see an IO difference).

Mind you, the CPU usage could still skyrocket. All this really does is get rid of some superfluous CPU cycles, so it will finish the job quicker. That's all.

Community
  • 1
  • 1
Oliver W.
  • 13,169
  • 3
  • 37
  • 50