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
Ваша помощь и пример наиболее ценятся!
Ответы
Ответ 1
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)
Ответ 2
Я не согласен с комментарием 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 пытается портировать в целом полезные числовые/код управления данными для нумерации. Кто знает, может быть, вы это сделаете?).
Вы заметите, что я не ответил (4), потому что это не имеет смысла. Таблицы не транспонируются в python или R. Массивы или матрицы. Итак, преобразуйте свои данные в массив с однородным dtype, а затем просто используйте myarray.T.
Другие инструменты, на которые вы можете обратить внимание, - это pytables (и связанный с ними пакетный ракурс), larry, datarray, pandas и табличные. В частности, datarray стремится создать систему для меченых массивов данных, которая послужила бы основой для других проектов (и я думаю, что разработчики также из проектов larry и pandas).
Надеюсь, что это поможет!
Дав
Ответ 3
Простой ответ: используйте pandas
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
Ответ 4
Там есть модуль для анализа 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
и передать ее каждой строке в цикле.