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 и передавая каждый ряд в цикле.

Другие вопросы по тегам