Python: как сделать основные манипуляции с данными, как в R?
Я работаю с R в течение нескольких лет. R очень силен в манипулировании данными. Я изучаю Python, и я хотел бы знать, как манипулировать данными с помощью Python. В основном мои наборы данных организованы в виде фреймов данных (например, таблица Excel). Я хотел бы знать (на примере), как такого рода основные задачи манипулирования данными могут быть выполнены с помощью Python?
1. Read csv file like the following
var1, var2, var3
1, 2, 3
4, 5, 6
7, 8, 9
2. Subset data where var2 in ('5', '8')
3. Make a new variable --> var4 = var3 * 3
4. Transpose this data
5. Write to csv file
Ваша помощь и пример очень ценятся!
4 ответа
import csv
from itertools import izip
with open('source.csv') as f:
reader = csv.reader(f)
# filter data
data = (row for row in reader if row[1].strip() in ('5', '8'))
# make a new variable
data = (row + [int(row[2]) * 3] for row in data)
# transpose data
data = izip(*data)
# write data to a new csv file
with open('destination.csv', 'w') as fw:
csv.writer(fw).writerows(data)
Я не согласен с комментарием Cpfohl - возможно, потому что сам прошел через этот же переход, и неясно, как наивный пользователь сможет сформулировать проблему более точно. На самом деле это активная проблема развития в настоящее время с рядом проектов, которые все предлагают непересекающиеся функциональные возможности (например, в мире финансовых временных серий, в мире изображений мозга и т. Д.).
Короткий ответ заключается в том, что различные библиотеки Python для работы с таблицами и CSV-файлами не так хороши для новичка, как библиотеки в R, которые являются конечным результатом многолетних пользователей разных уровней.
Во-первых, взгляните на записи в NumPy. Это, вероятно, самая близкая структура данных в широко используемой библиотеке, которая похожа на data.frame в R. В частности, вам, вероятно, понравится функция numpy.recfromcsv, хотя она не такая надежная, как, например, read.csv. в R (у него будут проблемы с нестандартными окончаниями строки, например).
Подмножество повторного массива легко (хотя его создание может показаться неуклюжим):
import numpy as np
mydata = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y', int)])
mydata = mydata.view(np.recarray)
mydata[mydata.x > 2]
Изменение природы массива Numpy обычно не так просто, как в R, но есть хорошая библиотека функций в numpy.lib.recfunctions
(который должен быть импортирован отдельно - он не идет вместе с простым import numpy
). В частности, проверьте rec_append_fields и rec_join для добавления столбцов.
Numpy имеет функцию numpy.savetxt
он примет простой аргумент-разделитель для создания CSV-файла, но он не будет печально печатать имена столбцов (по крайней мере, я этого не вижу). Поэтому, хотя я не рекомендую добавлять ненужные библиотеки (так как это дает менее переносимый код), вы можете просто использовать matplotlib.mlab.rec2csv
(вы также найдете некоторые другие подобные функции в этом районе - сообщество NumPy пытается перенести, как правило, полезный числовой код / код манипулирования данными на NUMPY. Кто знает, может быть, вы это сделаете?).
Вы заметите, что я не ответил (4), потому что это не имеет смысла. Таблицы не транспонируются в python или R. Массивы или матрицы делают. Итак, преобразуйте ваши данные в массив с одинаковым dtype, а затем просто используйте myarray.T.
Другие инструменты, на которые вы можете взглянуть, это pytables (и связанный с ним пакет carray), larry, datarray, pandas и tabular. В частности, datarray стремится создать систему для помеченных массивов данных, которая послужит основой для других проектов (и я думаю, что есть разработчики из проектов larry и pandas).
Надеюсь, это поможет! Dav
Простой ответ: используйте панд
1
In [2]: df = read_csv('foo.csv', index_col=None)
In [3]: df
Out[3]:
var1 var2 var3
0 1 2 3
1 4 5 6
2 7 8 9
2
In [4]: df[df['var2'].isin([5, 8])]
Out[4]:
var1 var2 var3
1 4 5 6
2 7 8 9
3
In [5]: df['var4'] = df['var3'] * 2
In [6]: df
Out[6]:
var1 var2 var3 var4
0 1 2 3 6
1 4 5 6 12
2 7 8 9 18
4
In [7]: df.T
Out[7]:
0 1 2
var1 1 4 7
var2 2 5 8
var3 3 6 9
var4 6 12 18
6
In [8]: df.to_csv('foo2.csv')
In [9]: !cat foo2.csv
index,var1,var2,var3,var4
0,1,2,3,6
1,4,5,6,12
2,7,8,9,18
В стандартной библиотеке есть модуль для разбора CSV. Чтобы получить список строк, каждая из которых содержит список ячеек, вы можете использовать list(csv.reader(...))
,
Шаг 2 и 3 могут быть записаны в одном списке понимания: [(var1, var2, var3, var3 * 3) for var1, var2, var3 in data if var2 in ('5', '8')]
,
Я ничего не знаю в стандартной библиотеке для транспонирования списков списков. Возможно, в NumPy или SciPy есть что-то. Быстрым и грязным способом было бы застегивать строки (zip(*lists)
).
Обратная запись в файл должна быть такой же простой, как создание csv.writer
и передавая каждый ряд в цикле.