Итеративно читаемый (tsv) файл для Pandas DataFrame

У меня есть некоторые экспериментальные данные, которые выглядят так: http://paste2.org/YzJL4e1b (слишком долго, чтобы размещать здесь). Блоки, разделенные строками имен полей, являются разными испытаниями одного и того же эксперимента - я хотел бы прочитать все в кадре данных pandas, но он должен объединить определенные испытания (например, 0,1,6,7 вместе взятые - и 2,3,4,5 вместе взятые в другой группе). Это связано с тем, что в разных исследованиях условия немного отличаются, и я хотел бы проанализировать разницу результатов между этими условиями. У меня есть список номеров для разных условий из другого файла.

В настоящее время я делаю это:

tracker_data = pd.DataFrame
tracker_data = tracker_data.from_csv(bhpath+i+'_wmet.tsv', sep='\t', header=4)
tracker_data['GazePointXLeft'] = tracker_data['GazePointXLeft'].astype(np.float64) 

но это, конечно, просто читает все за один раз (включая строки с именами полей) - было бы здорово, если бы я мог как-то вкладывать блоки, что позволяет мне легко получить к ним доступ через числовые индексы...

У вас есть идеи, как мне лучше всего это сделать?

3 ответа

Решение

Вы должны использовать read_csv скорее, чем from_csv *:

tracker_data = pd.read_csv(bhpath+i+'_wmet.tsv', sep='\t', header=4)

Если вы хотите присоединиться к списку таких фреймов, вы можете использовать concat:

trackers = (pd.read_csv(bhpath+i+'_wmet.tsv', sep='\t', header=4) for i in range(?))
df = pd.concat(trackers)

* который я считаю устаревшим.

Я сделал это итеративно. очень итеративно. Ничто другое, кажется, не работает.

pat = 'TimeStamp    GazePointXLeft  GazePointYLeft  ValidityLeft    GazePointXRight GazePointYRight ValidityRight   GazePointX  GazePointY  Event'
with open(bhpath+fileid+'_wmet.tsv') as infile:
    eye_data = infile.read().split(pat)
    eye_data = [trial.split('\r\n') for trial in eye_data] # split at '\r'
    for idx, trial in enumerate(eye_data):
        trial = [row.split('\t') for row in trial]
        eye_data[idx] = trial

У меня не совсем получилось, но я думаю, это из-за того, как я копировал / вставлял данные. Попробуйте, дайте мне знать, если это не сработает.

Используя вдохновение из этого вопроса

pat = "TimeStamp\tGazePointXLeft\tGazePointYLeft\tValidityLeft\tGazePointXRight\tGazePointYRight\tValidityRight\tGazePointX\tGazePointY\tEvent\n"
with open('rec.txt') as infile:
    header, names, tail = infile.read().partition(pat)

names = names.split()  # get rid of the tabs here
all_data = tail.split(pat)
res = [pd.read_csv(StringIO(x), sep='\t', names=names) for x in all_data]

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

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

Для больших файлов вы можете написать генератор для чтения, пока не нажмете имена столбцов и напишите новый файл, пока не нажмете их снова. Затем прочитайте их отдельно, используя что-то вроде ответа Энди.

Отдельный вопрос от того, как работать с несколькими блоками. Предполагая, что у вас есть список Dataframeс, который я назвал resВы можете использовать concat от pandas, чтобы объединить их в один DataFrame с MultiIndex (см. также ссылку Энди).

In [122]: df = pd.concat(res, axis=1, keys=['a', 'b', 'c'])  # Use whatever makes sense for the keys

In [123]: df.xs('TimeStamp', level=1, axis=1)
Out[123]: 
     a    b    c
0  NaN  NaN  NaN
1  0.0  0.0  0.0
2  3.3  3.3  3.3
3  6.6  6.6  6.6
Другие вопросы по тегам