У меня есть пример набора данных в csv. Он имеет только ~ 50 тыс. Строк. Я хочу проверить производительность SQL-запросов на этот набор данных, но для этой цели слишком мало строк 50K. Каков наилучший способ взять существующий csv и создать новый, который в N раз больше исходного, и каждая строка дублируется N раз?
Например, если N = 5
И вход csv:
col1, col2, col3
1, 'some string', '1999-01-01'
2, 'another string', '2001-01-01'
Желательным выходом csv будет:
col1, col2, col3
1, 'some string', '1999-01-01'
2, 'another string', '2001-01-01'
1, 'some string', '1999-01-01'
2, 'another string', '2001-01-01'
1, 'some string', '1999-01-01'
2, 'another string', '2001-01-01'
1, 'some string', '1999-01-01'
2, 'another string', '2001-01-01'
1, 'some string', '1999-01-01'
2, 'another string', '2001-01-01'
решения bash, python или SQL приветствовали
bash или python, потому что я тестирую несколько платформ баз данных
Использование bash:
n=5
(head -n1 file; for i in $(seq 1 $n); do tail -n+2 file; done) > output.csv
Команда head
отображает заголовок.
Для выполнения for
5 раз tail
команды отображает содержимое file
кроме первой строки (-n+2
устанавливает смещение во вторую строку).
Для этой цели я сделал небольшой скрипт python:
# mulcsv.py
import sys
def main(fname_in, fname_out, N):
header = None
content = []
with open(fname_in, "r") as fin:
for linenr, line in enumerate(fin,1):
# remove NL? line = line.strip()
if linenr==1:
header = line
else:
content.append(line)
with open(fname_out, "w") as fout:
fout.write(header)
for nr in range(N):
fout.write("".join(content))
print("Output in %s" % fname_out)
if __name__=="__main__":
if len(sys.argv)!=4:
print("Usage: %s <fname-in>.csv <fname-out>.csv N" % (sys.argv[0],))
sys.exit(0)
# TODO: check and parse arguments (in file existing, N is positive integer) - use argsparse?
main(fname_in = sys.argv[1], fname_out = sys.argv[2], N = int(sys.argv[3]))
# TESTING: main(fname_in = "r.csv", fname_out = "r2.csv", N = 5)
И назовите это:
python mulcsv.py input.csv output.csv 5
Для правильной проверки аргументов/синтаксического анализа используйте argsparse.
Поскольку вы не указали, с какой RDBMS вы планируете выполнить свой SQL, я дам вам решение для PostgreSQL.
Во-первых, вы можете скопировать данные CSV в PostgreSQL с помощью команды COPY.
Затем вы можете использовать функцию generate_series для расширения ваших данных, как это (CTE csv предназначен только для тестирования):
with srs as (
select a
from generate_series(0,99) a
),
csv as (
select *
from mycsv
)
select *
from csv
join srs on true
Отрегулируйте в соответствии с вашими потребностями. Это генерирует в 99 раз больше, чем в CTE csv.