У меня есть несколько очень больших файлов CSV (+ 15Gb), которые содержат 4 начальных строки метаданных / информации заголовка, а затем данные. Первые 3 столбца являются трехмерными декартовыми координатами и являются значениями, которые мне нужно изменить с помощью основных математических операций. например, сложение, вычитание, умножение, деление. Мне нужно сделать это по массе для каждого из столбцов координат. Первые 3 столбца являются значениями типа с плавающей запятой
Остальные столбцы в CSV могут быть любого типа, например, string, int, et c ....
В настоящее время я использую скрипт, в котором я могу прочитать в каждой строке CSV и внести изменения, а затем записать в новый файл, и, кажется, работает нормально. Но проблема в том, что на большие файлы уходят дни. Машина, на которой я работаю, имеет много памяти (120 Гб), но в текущем методе это не используется.
Я знаю, что могу обновить столбец по массе, используя массив numpy 2D, если пропущу 4 строки метаданных. Например,
arr = np.genfromtxt(input_file_path, delimiter=',', skip_header=4)
arr[:,0]=np.add(arr[:,0],300)
. Это обновит первый столбец, добавив 300 к каждому значению. Но проблема с попыткой использования numpy состоит в том, что
Numpy массивы не поддерживают смешанные типы данных для остальных столбцов, которые будут импортированы (я не Я не знаю, что будут содержать другие столбцы, поэтому я не могу использовать структурированные массивы - или, скорее, я хочу, чтобы это был универсальный инструмент, поэтому мне не нужно знать, что они будут содержать)
Я могу экспортировать массив numpy в csv (при условии, что это не смешанные типы), и просто используя обычные текстовые функции, я могу создать отдельный CSV для 4 строк метаданных, но затем мне нужно как-то объединить их, и я не Я не хочу читать все строки данных CSV, просто чтобы добавить их в конец метаданных CSV.
Я знаю, смогу ли я сделать эту работу с Numpy it значительно увеличит скорость, используя большой объем памяти машины, удерживая весь CSV в памяти во время выполнения операций. Я никогда не использовал pandas, но также рассмотрел бы использование его для решения. Я немного заглянул в pandas, думая, что, возможно, смогу сделать это с кадрами данных, но мне все еще нужно выяснить, как иметь 4 строки в качестве заголовка моего столбца вместо одного, и, кроме того, я не видел способа применить массовое обновление ко всему столбцу (как я могу с numpy) без использования python l oop - не уверен, замедлит ли это или нет, если он уже находится в памяти.
Метаданные могут быть пустыми для строк 2,3,4, но в большинстве случаев в строке 4 будет записан тип данных. В дополнение к начальным 3 столбцам координат может быть до 200 столбцов данных.
Мой текущий (медленный) код выглядит следующим образом:
import os
import subprocess
import csv
import numpy as np
def move_txt_coords_to(move_by_coords, input_file_path, output_file_path):
# create new empty output file
open(output_file_path, 'a').close()
with open(input_file_path, newline='') as f:
reader = csv.reader(f)
for idx, row in enumerate(reader):
if idx < 4:
append_row(output_file_path, row)
else:
new_x = round(float(row[0]) + move_by_coords['x'], 3)
new_y = round(float(row[1]) + move_by_coords['y'], 3)
new_z = round(float(row[2]) + move_by_coords['z'], 3)
row[0] = new_x
row[1] = new_y
row[2] = new_z
append_row(output_file_path, row)
def append_row(output_file, row):
f = open(output_file, 'a', newline='')
writer = csv.writer(f, delimiter=',')
writer.writerow(row)
f.close()
if __name__ == '__main__':
move_by_coords = {
'x': -338802.5,
'y': -1714752.5,
'z': 0
}
input_file_path = r'D:\incoming_data\large_data_set1.csv'
output_file_path = r'D:\outgoing_data\large_data_set_relocated.csv'
move_txt_coords_to(move_by_coords, input_file_path, output_file_path)