Объединение нескольких csv-файлов в один csv с одним и тем же заголовком-Python
в настоящее время я использую приведенный ниже код для импорта 6,000 csv-файлов (с заголовками) и экспорта их в один csv-файл (с одной строкой заголовка).
#import csv files from folder
path =r'data/US/market/merged_data'
allFiles = glob.glob(path + "/*.csv")
stockstats_data = pd.DataFrame()
list_ = []
for file_ in allFiles:
df = pd.read_csv(file_,index_col=None,)
list_.append(df)
stockstats_data = pd.concat(list_)
print(file_ + " has been imported.")
этот код работает нормально, но он медленный. Это может занять до 2 дней.
мне был предоставлен однострочный скрипт для командной строки терминала, который делает то же самое (но без заголовков). Этот сценарий занимает 20 секунд.
for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done
кто-нибудь знает, как я могу ускорить первый скрипт на Python? К сократив время, я подумал о том, чтобы не импортировать его в фрейм данных и просто объединить CSV, но я не могу понять это.
спасибо.
3 ответов
Если вам не нужен CSV в памяти, просто копируя с входа на выход, будет намного дешевле избежать синтаксического анализа вообще и копировать без создания в памяти:
import shutil
#import csv files from folder
path = r'data/US/market/merged_data'
allFiles = glob.glob(path + "/*.csv")
with open('someoutputfile.csv', 'wb') as outfile:
for i, fname in enumerate(allFiles):
with open(fname, 'rb') as infile:
if i != 0:
infile.readline() # Throw away header on all but first file
# Block copy rest of file from input to output without parsing
shutil.copyfileobj(infile, outfile)
print(fname + " has been imported.")
вот так:shutil.copyfileobj
обрабатывает эффективное копирование данных, резко уменьшая работу уровня Python для анализа и ресериализации.
предполагается, что все CSV-файлы имеют одинаковый формат, кодировку, окончания строк и т. д., и заголовок не содержит встроенных новых строк, но если это так, это намного быстрее, чем альтернативы.
вы должны сделать это в Python? Если вы открыты для этого полностью в оболочке, все, что вам нужно сделать, это сначала cat
строка заголовка из случайно выбранного ввода .csv файл в merged.csv
перед запуском one-liner:
cat a-randomly-selected-csv-file.csv | head -n1 > merged.csv
for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done
вам не нужны панды для этого, просто csv
модуль будет работать нормально.
import csv
df_out_filename = 'df_out.csv'
write_headers = True
with open(df_out_filename, 'wb') as fout:
writer = csv.writer(fout)
for filename in allFiles:
with open(filename) as fin:
reader = csv.reader(fin)
headers = reader.next()
if write_headers:
write_headers = False # Only write headers once.
writer.writerow(headers)
writer.writerows(reader) # Write all remaining rows.