Написать миллионы строк в файл - питон, таблиц данных и Redis


У меня есть следующий фрагмент кода, который считывает CSV в таблицы данных, и записывает ключ-значение пары в файл в Redis для протокола-режиме, т. е. SET key1 value1. Код по частям и я пытался использовать многопроцессорность, хотя я не уверен в его эффективности (прибыли).

CSV-файл имеет около 6 миллионов строк, читать в таблицу данных довольно быстро (до 2 минут). Выходной файл имеет 12 миллионов линий (2 линии в каждой строке входного файла). Это займет около 50 минут. Может какой-либо части моего кода оптимизировать/изменить, чтобы сделать это быстрее работать? После закрытия файла, загрузка его в Redis занимает менее 90 секунд. Узким местом действительно является записью в файл.

Я смотрел на загрузку всех строк я создания в таблицы данных, а затем использовать to_csv (функция), чтобы сбросить его в файл, но я не уверен, как оно будет.

filepath = '/path/to/file.csv'

def df_to_file:
    df = pd.read_csv(filepath)
    f = open('output_file', 'w')
    for i in range(len(df.index)):
        if df['col1'].iloc[i] != '':
            key1 = str_const1+str(df['col1'].iloc[i])+str(df['col4'].iloc[i])+str(df['col5'].iloc[i])+...+str(df['col_n'].iloc[i])
            val1 = df['col_n+1'].iloc[i]

            key1a = str_const1a+str(df['col1'].iloc[i])+str(df['col4'].iloc[i])+str(df['col5'].iloc[i])+...+str(df['col_n'].iloc[i])
            val1a = df['col_n+2'].iloc[i]

            print('SET {0} {1}\nSET {0} {1}'.format(key1, val1, key1a, val1a), file = f)

        if df['col2'].iloc[i] != '':
            key1 = str_const2+str(df['col2'].iloc[i])+str(df['col4'].iloc[i])+str(df['col5'].iloc[i])+...+str(df['col_n'].iloc[i])
            val1 = df['col_n+1'].iloc[i]

            key1a = str_const2a+str(df['col2'].iloc[i])+str(df['col4'].iloc[i])+str(df['col5'].iloc[i])+...+str(df['col_n'].iloc[i])
            val1a = df['col_n+2'].iloc[i]

            print('SET {0} {1}\nSET {0} {1}'.format(key1, val1, key1a, val1a), file = f)
        if df['col3'].iloc[i] != '':
            key1 = str_const3+str(df['col3'].iloc[i])+str(df['col4'].iloc[i])+str(df['col5'].iloc[i])+...+str(df['col_n'].iloc[i])
            val1 = df['col_n+1'].iloc[i]

            key1a = str_const3a+str(df['col3'].iloc[i])+str(df['col4'].iloc[i])+str(df['col5'].iloc[i])+...+str(df['col_n'].iloc[i])
            val1a = df['col_n+2'].iloc[i]

            print('SET {0} {1}\nSET {0} {1}'.format(key1, val1, key1a, val1a), file = f)
    f.close()

p = Process(target = df_to_file)
p.start()
p.join() 


Комментарии
1 ответ

Я не жесткий Pythonista, но некоторые моменты я могу думать, являются:


  • Назначение key1, val1, ... появляются ненужные, так как они используются только один раз при вызове format()

  • Расторгнуть каждого if С continueили использовать elseкак оказалось, что только одна ветвь выполняется в каждой итерации серии. Порядок, условия, в соответствии с ожидаемым распределением данных, если это возможно (т. е. наиболее часто вычисляется в true условие наступит первым)

  • Попробуйте написать меньше, например, посмотреть, если вы можете использовать MSET бриться несколько байт в каждой итерации (миллионы, это может иметь значительные последствия ;))

Наконец, похоже, что вы не используете последние два аргумента вы передаете formatтак если это не опечатка вы можете удалить их также.

2
ответ дан 10 февраля 2018 в 05:02 Источник Поделиться