2010-09-27 3 views
17

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

Вот мои данные:

col1 col2 col3 col4 col5 
100002 2006 1.1 0.01 6352 
100002 2006 1.2 0.84 304518 
100002 2006 2 1.52 148219 
100002 2007 1.1 0.01 6292 
10002 2006 1.1 0.01 5968 
10002 2006 1.2 0.25 104318 
10002 2007 1.1 0.01 6800 
10002 2007 4 2.03 25446 
10002 2008 1.1 0.01 6408 

Я хочу подмножество данных на основе содержимого col1 и col2. (Уникальные значения в col1 равны 100002 и 10002, а в col2 - 2006,2007 и 2008.)

Это можно сделать в R с помощью команды подмножества, есть ли что-то подобное в Python?

ответ

20

Хотя итераторы на основе ответов прекрасно, если вы работаете с Numpy массивами (как вы говорите, что вы есть) есть лучшие и быстрые способы выбора вещей:

import numpy as np 
data = np.array([ 
     [100002, 2006, 1.1, 0.01, 6352], 
     [100002, 2006, 1.2, 0.84, 304518], 
     [100002, 2006, 2, 1.52, 148219], 
     [100002, 2007, 1.1, 0.01, 6292], 
     [10002, 2006, 1.1, 0.01, 5968], 
     [10002, 2006, 1.2, 0.25, 104318], 
     [10002, 2007, 1.1, 0.01, 6800], 
     [10002, 2007, 4, 2.03, 25446], 
     [10002, 2008, 1.1, 0.01, 6408] ]) 

subset1 = data[data[:,0] == 100002] 
subset2 = data[data[:,0] == 10002] 

Это дает

subset1:

array([[ 1.00002e+05, 2.006e+03, 1.10e+00, 1.00e-02, 6.352e+03], 
     [ 1.00002e+05, 2.006e+03, 1.20e+00, 8.40e-01, 3.04518e+05], 
     [ 1.00002e+05, 2.006e+03, 2.00e+00, 1.52e+00, 1.48219e+05], 
     [ 1.00002e+05, 2.007e+03, 1.10e+00, 1.00e-02, 6.292e+03]]) 

subset2:

array([[ 1.0002e+04, 2.006e+03, 1.10e+00, 1.00e-02, 5.968e+03], 
     [ 1.0002e+04, 2.006e+03, 1.20e+00, 2.50e-01, 1.04318e+05], 
     [ 1.0002e+04, 2.007e+03, 1.10e+00, 1.00e-02, 6.800e+03], 
     [ 1.0002e+04, 2.007e+03, 4.00e+00, 2.03e+00, 2.5446e+04], 
     [ 1.0002e+04, 2.008e+03, 1.10e+00, 1.00e-02, 6.408e+03]]) 

Если вы не знали уникальных значений в первой колонке заранее, вы можете использовать либо numpy.unique1d, либо встроенную функцию set, чтобы найти их.

Edit: я просто понял, что вы хотите, чтобы выбрать данные, где у вас есть уникальные комбинации двух колонн ... В этом случае, вы могли бы сделать что-то вроде этого:

col1 = data[:,0] 
col2 = data[:,1] 

subsets = {} 
for val1, val2 in itertools.product(np.unique(col1), np.unique(col2)): 
    subset = data[(col1 == val1) & (col2 == val2)] 
    if np.any(subset): 
     subsets[(val1, val2)] = subset 

(я, хранящую подмножества как dict, причем ключ является кортежем комбинации ... Есть, конечно, другие (и лучше, в зависимости от того, что вы делаете) способы сделать это!)

+0

Спасибо! Оглядываясь назад, это настолько очевидно, что я должен был попробовать это сам, но ваше объяснение очень полно. Однако знаете ли вы, какую скорость мы можем получить, используя этот подход, по сравнению с итераторами?Я думал, что итераторы тоже очень быстры! – user308827

+0

@ user308827 - Они есть, но если вы работаете с массивами numpy, а не с списками, использование numpy-способа делать вещи будет быстрее. Вообще говоря, итерация через весь массив numpy медленная. Решения на основе итератора должны проходить через каждый элемент в python. Когда вы выбираете подмножество массива numpy с использованием массива boolean numpy, итерация выполняется за кулисами в скомпилированном коде. (Я просто упрощаю здесь, но это суть, во всяком случае). В принципе, если вы используете массивы numpy для хранения ваших данных, быстрее работать с ними с помощью функций numpy. –

+0

Также есть способ объединить 2 условия в подмножество? Например, subset1 = data [(data [:, 0] == 100002) и (data [:, 1] == 2007)], похоже, не работают. благодаря! – user308827

2

Поскольку я не знаком с R и как эта команда подмножества работает на основе вашего описания, я могу предложить вам взглянуть на функциональность группы itertool. Если задана функция, которая выводит значение, вы можете сформировать группы на основе вывода этой функции. Взятые из groupby:

groups = [] 
uniquekeys = [] 
data = sorted(data, key=keyfunc) 
for k, g in groupby(data, keyfunc): 
    groups.append(list(g))  # Store group iterator as a list 
    uniquekeys.append(k) 

, а затем у вас есть свои подмножества. Однако будьте осторожны, поскольку возвращаемые значения не являются полноценными списками. Они итераторы.

Я предполагаю, что ваши значения возвращаются по очереди за строкой.

+0

Спасибо! Это полезно. – user308827

5

subset() in R в значительной степени аналогичен filter() в Python. Как эталонные примечания, это будет использоваться неявно списковыми, поэтому наиболее краткий и ясный способом, чтобы написать код может быть

[ item for item in items if item.col2 == 2006 ] 

, если, например, ваши ряды данных были в итераторе называются items.

+0

Спасибо! Я добавлю фильтр в свой список команд, чтобы запомнить – user308827