Написание CSV-файлов с Python с точными параметрами форматирования - PullRequest
2 голосов
/ 29 мая 2010

У меня проблемы с обработкой некоторых файлов данных CSV для проекта. Кто-то предложил использовать python / csv reader, чтобы помочь разбить файлы, с которыми у меня был некоторый успех, но я не смог их использовать.

Этот код немного отличается от того, что я пробовал раньше. По сути, я пытаюсь создать массив. В формате необработанных данных первые 7 строк не содержат данных, а затем каждый столбец содержит 50 экспериментов, каждый из которых содержит 4000 строк, всего 200 000 строк. То, что я хочу сделать, это взять каждый столбец и сделать его отдельным CSV-файлом с каждым экспериментом в отдельном столбце. Таким образом, это будет массив из 50 столбцов и 4000 строк для каждого типа данных. Код здесь разрушает правильные значения, я думаю, что логика в порядке, но это противоречит тому, как я этого хочу. Я хочу разделители без кавычек (запятые и пробелы), и я хочу, чтобы значения элементов в кавычках. Прямо сейчас это делает противоположное для обоих значений элементов без кавычек и разделителей в кавычках. Я потратил несколько часов, пытаясь понять, как это сделать, но безрезультатно,

import csv  

ifile  = open('00_follow_maverick.csv')  
epistemicfile = open('00_follower_maverick_EP.csv', 'w')  

reader = csv.reader(ifile)  

colnum = 0  
rownum = 0  
y = 0  
z = 8   
for column in reader:  
    rownum = 4000 * y + z  
    for element in column:  
        writer = csv.writer(epistemicfile)  
        if y <= 50:  
            y = y + 1  
            writer.writerow([element])  
            writer.writerow(',')  
            rownum = x * y + z  
        if y > 50:  
            y = 0  
            z = z + 1  
            writer.writerow(' ')  
            rownum = x * y + z  
        if z >= 4008:  
            break  

Что происходит: я беру каждую строку в файле необработанных данных с итерациями по 4000, чтобы разделить их запятыми для 50 экспериментов. Когда y, индикатор эксперимента здесь, достигает 50, он возвращается к эксперименту 0 и добавляет 1 к z, что говорит ему, на какую строку смотреть, по формуле 4000 * y + z. Когда он завершает строки для всех 50 экспериментов, он заканчивается. Проблема в том, что я не знаю, как заставить python записывать фактические значения в кавычки, а мои разделители вне кавычек.

Любая помощь будет наиболее ценной. Извиняюсь, если это кажется глупым вопросом, у меня нет опыта программирования, это моя первая попытка. Спасибо.

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

Миниатюрный пример необработанного файла выглядит так:

column1             column2            column3
exp1data1time1      exp1data2time1     exp1data3time1
exp1data1time2      exp1data2time2     exp1data3time2
exp2data1time1      exp2data2time1     exp2data3time1
exp2data1time2      exp2data2time2     exp2data3time2
exp3data1time1      exp3data2time1     exp3data3time1
exp3data1time2      exp3data2time2     exp3data3time2

Итак, фактическая версия имеет 4000 строк вместо 2 для каждого нового эксперимента. В фактической версии 40 столбцов, но в основном тип данных в необработанном файле соответствует номеру столбца. Я хочу разделить каждый тип данных или столбца в отдельный файл CSV.

Это будет выглядеть так:

csv file1

exp1data1time1   exp2data1time1   exp3data1time1   
exp1data1time2   exp2data1time2   exp3data1time2

csv file2

exp1data2time1   exp2data2time1   exp3data2time1   
exp1data2time2   exp2data2time2   exp3data2time2

csv file3

exp1data3time1   exp2data3time1   exp3data3time1   
exp1data3time2   exp2data3time2   exp3data3time2

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

Ответы [ 3 ]

2 голосов
/ 29 мая 2010

Если бы у меня была кошка каждый раз, я видел базу данных биологических, психологических или химических веществ в этом состоянии:

"каждый столбец содержит 50 экспериментов, каждый с 4000 строк, на 200000 некоторые Всего строк. Что я хочу сделать, это взять каждый столбец, и сделать его отдельным CSV-файл, с каждым экспериментом в своем собственная колонка. Так что это будет массив 50 столбцов и 4000 строк для каждой информации типа "

Я бы слишком много гулял со многими кошками.

Я даже не посмотрел на ваш код, потому что предложенная вами перестройка - это просто еще одна проблема, которую нужно решить. Я не виню тебя, ты утверждаешь, что ты новичок, и все твои сверстники делают такую ​​же ошибку. Начинающие программисты, которым еще предстоит понять, как использовать массивы, часто сталкиваются с объявлениями переменных, такими как:

integer response01, response02, response03, response04, ...

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

Вы должны прочитать и понять, почему нормализация базы данных была разработана, кодифицирована и стала доминировать в том, как люди думают о структурированных данных. Одной статьи в Википедии может быть недостаточно. Используя приведенный мной пример, я попытаюсь объяснить, как я к этому отношусь. Ваши данные состоят из наблюдений; Иными словами, первичные данные - это единичное наблюдение. Это наблюдение имеет контекст: это один из 4000 наблюдений, каждый из которых принадлежит одному из 50 экспериментов. Если бы вам пришлось прикреплять контекст к каждому наблюдению, вы бы получили схему адресации, которая выглядит следующим образом:

<experiment_number, observation_number, value>

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

<experiment_number, protocol_number, observation_number, value>

где протоколом может быть какая-то форма переменного типа лечения - скажем, pH. Но обратите внимание, что я не назвал протокол pH и я не записал его как таковой в базу данных. Тогда мне понадобится вспомогательная таблица с соответствующими параметрами протокола, , например, :

<protocol_number, acidity, temperature, pressure>

Теперь мы только что создали «отношение», о котором любят говорить те, кто работает с базой данных; мы также начали нормализацию данных. Если вам нужно знать pH для данного протокола, в единственном ряду таблицы протокола есть единственное и единственное место, где его можно найти. Обратите внимание, что я отделил данные, которые так хорошо сочетаются друг с другом на листе данных, и из таблицы наблюдений я не могу увидеть pH для конкретного dataum. Но это нормально, потому что я могу просто посмотреть это в своей таблице протоколов, если это необходимо. Это «реляционное соединение», и если бы мне было нужно, я мог бы объединить все различные параметры из всех различных таблиц и воссоздать исходную таблицу данных в ее исходной неструктурированной форме.

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

0 голосов
/ 29 мая 2010

нормализующий код

#!/usr/bin/python

"""parses a csv file containing a particular data layout and normalizes

    The raw data set is a csv file of the form::

        column1                column2               column3
        exp01data01time01      exp01data02time01     exp01data03time01
        exp01data01time02      exp01data02time02     exp01data03time02

    where there are 40 such columns and the literal column title
    is added as context to the output row

    it is assumed that the columns are comma separated but
    the lexical form of the subcolumns is unspecified.

    Output will consist of a single CSV output stream
    on stdout of the form::

        exp01, time01, data01, column1

    for varying actual values of each field.
"""

import csv
import sys

def split_subfields(s):
    """returns a list of subfields of s
       this function is expected to be re-written to match the actual,
       unspecified lexical structure of s."""
    return [s[0:5], s[5:11], s[11:17]]


def normalise_data(reader, writer):
    """returns a list of the column headings from the reader"""

    # obtain the headings for use in normalization
    names = reader.next()

    # get the data rows, split them out by column, add the column name
    for row in reader:
        for column, datum in enumerate(row):
            fields = split_subfields(datum)
            fields.append(names[column])
            writer.writerow(fields)

def main():
    if len(sys.argv) != 2:
        print  >> sys.stderr,  ('usage: %s input.csv' % sys.argv[0])
        sys.exit(1)

    in_file = sys.argv[1]

    reader = csv.reader(open(in_file))
    writer = csv.writer(sys.stdout)
    normalise_data(reader, writer)

if __name__ == '__main__': main()

Так, что команда python epistem.py raw_data.csv > cooked_data.csv дает отрывочный вывод, похожий на:

exp01,data01,time01,column1
...
exp01,data40,time01,column40
exp01,data01,time02,column1
exp01,data01,time03,column1
...
exp02,data40,time15,column40
0 голосов
/ 29 мая 2010

Нормализация набора данных

Спасибо за пример. У вас есть контекст, который я уже описал, возможно, я смогу прояснить его.

column1             column2            column3
exp1data1time1      exp1data2time1     exp1data3time1
exp1data1time2      exp1data2time2     exp1data3time2

Колонны - это выдумка, сделанная последним парнем; то есть они не несут соответствующей информации. При анализе в обычной форме ваши данные выглядят так же, как мой первый предложенный кортеж:

<experiment_number, time, response_number, response>

где я подозреваю time может фактически означать "subject_id" или "trial_number". Для вас может показаться неуместным объединить все различные значения response в один набор данных; действительно, основываясь на желаемом выводе, я подозреваю, что это так. На первый взгляд, возражение «но ответ субъекта на вопрос об эпистемологических свойствах стульев не имеет никакого отношения к их метаэпистемическим убеждениям относительно цвета», но это было бы ошибочным. Данные связаны, потому что они имеют общий экспериментальный предмет, и самокорреляция является важной концепцией в социологической аналитике.

Например, вы можете обнаружить, что респондент A дает те же ответы, что и респондент B, за исключением того, что все ответы A смещены на один уровень выше из-за того, что субъект понял критерии. Это очень сильно изменило бы абсолютные значения данных, но я надеюсь, что вы видите, что вопрос "действительно ли А и В имеют разные эпистемологические модели?" является значимым и действительным. Один метод моделирования данных позволяет легко ответить на этот вопрос, а желаемый метод - нет.

Рабочий код синтаксического анализа, который вскоре будет представлен.

...