транспонировать CSV-файл с C # или другой программой - PullRequest
0 голосов
/ 05 мая 2011

Я использую C # и записываю свои данные в файлы csv (для дальнейшего использования).Однако мои файлы выросли в больших масштабах, и я должен их транспонировать.какой самый простой способ сделать этов любой программе?

Gil

Ответы [ 3 ]

2 голосов
/ 10 мая 2011

В порядке возрастания сложности (а также в порядке возрастания способности обрабатывать большие файлы):

  • Считать все это в двумерный массив (или зубчатый массив, называемый массивом массивов).).
    • Требуемая память: равна размеру файла

  • Отслеживать смещение файла в каждой строке.Начните с поиска каждой (не заключенной в кавычки) новой строки, сохраняя текущую позицию в List<Int64>.Затем выполните итерацию по всем строкам для каждой строки: найдите сохраненную позицию, скопируйте одну ячейку на выход и сохраните новую позицию.Повторяйте, пока у вас не закончатся столбцы (все строки достигают новой строки).
    • Требуемая память: восемь байт на строку
    • Частые операции поиска файлов, разбросанные по файлу, значительно превышающему размер кэша диска, приводят к перегрузке диска и снижению производительности, но не приводят к сбою.

  • Как и выше, но работает с блоками, например, по 8 тыс. Строк.Это создаст набор файлов, каждый с 8k столбцами.Блок ввода и вывода вписывается в дисковый кэш, поэтому перебора не происходит.После создания файлов полосы выполните итерацию по полосам, прочитав по одной строке из каждого и добавив к выводу.Повторите для всех строк.Это приводит к последовательному сканированию каждого файла, что также имеет очень разумное поведение кеша.
    • Требуемая память: 64 КБ для первого прохода, (количество столбцов / 8 КБ) файловых дескрипторов для второго прохода.
    • Хорошая производительность для таблиц до нескольких миллионов в каждом измерении.Для еще больших наборов данных объедините несколько полосовых файлов (например, 1 КБ), сделав меньший набор больших полос, повторяйте, пока у вас не будет только одной полоски со всеми данными в одном файле.

Заключительный комментарий: Вы можете уменьшить производительность, используя C ++ (или любой язык с надлежащей поддержкой указателей), отображаемые в память файлы и указатели вместо смещений файлов.

0 голосов
/ 10 мая 2011

Я написал небольшой скрипт для проверки концепции здесь, на python. Я признаю, что он глючит и, вероятно, будут сделаны некоторые улучшения производительности, но он это сделает. Я запустил файл 40x40 и получил желаемый результат. Я начал работать с чем-то более похожим на ваш пример данных, и мне потребовалось слишком много времени для ожидания.

path = mkdtemp()
try :
    with open('/home/user/big-csv', 'rb') as instream:
        reader = csv.reader(instream)        
        for i, row in enumerate(reader):
            for j, field in enumerate(row):                
                with open(join(path, 'new row {0:0>2}'.format(j)), 'ab') as new_row_stream:
                    contents = [ '{0},'.format(field) ]
                    new_row_stream.writelines(contents)
            print 'read row {0:0>2}'.format(i)
    with open('/home/user/transpose-csv', 'wb') as outstream:
        files = glob(join(path, '*'))
        files.sort()
        for filename in files:
            with open(filename, 'rb') as row_file:
                contents = row_file.readlines()          
                outstream.writelines(contents + [ '\n' ]) 
finally:
    print "done"
    rmtree(path)
0 голосов
/ 05 мая 2011

Это действительно зависит.Вы получаете это из базы данных?Вы можете использовать оператор импорта MySql.http://dev.mysql.com/doc/refman/5.1/en/load-data.html

Или вы можете использовать цикл данных, добавляя их в поток файлов с помощью объекта streamwriter.

StreamWriter sw = new StreamWriter('pathtofile');
foreach(String[] value in lstValueList){
String something = value[1] + "," + value[2];
sw.WriteLine(something);
}
...