2017-01-30 4 views
0

Код идет что-то вроде этого:подсчет частоты с использованием itertools.groupby() с recarray

>>>data = pd.DataFrame({'P': ['p1', 'p1', 'p2'], 
         'Q': ['q1', 'q2', 'q1'], 
         'R': ['r1', 'r1', 'r2']}) 

>>>data 

    P Q R 
0 p1 q1 r1 
1 p1 q2 r1 
2 p2 q1 r2 

>>>data.groupby(['R'] + ['P','Q']).size().unstack(['P','Q']) 

После переиндексации и fillna (0) дает следующий результат:

P p1  p2 
Q q1 q2 q1 q2 
R 
r1 1 1 0 0 
r2 0 0 1 0 

Я хотел сделайте то же самое с повторной попыткой, чтобы я импортировал itertools и попробовал следующее:

>>>data = np.array([('p1', 'p1', 'p2'), ('q1', 'q2', 'q1'), ('r1', 'r1', 'r2')], 
        dtype=[('P',object),('Q',object),('R',object)]).view(np.recarray) 

>>>groupby(data,key = (['R']+['P','Q'])).size().unstack(['P','Q']) 

Это не работает. Как достичь аналогичного результата без использования панд?

ответ

1

Давайте вернемся от фантазии и типа объекта. Он ничего нам не покупает.

Данные могут быть простой 2d массив строк:

In [711]: data = np.array([('p1', 'p1', 'p2'), ('q1', 'q2', 'q1'), ('r1', 'r1', 'r2')]) 
In [712]: data 
Out[712]: 
array([['p1', 'p1', 'p2'], 
     ['q1', 'q2', 'q1'], 
     ['r1', 'r1', 'r2']], 
     dtype='<U2') 

еще лучше, сделать это список списков:

In [713]: data.tolist() 
Out[713]: [['p1', 'p1', 'p2'], ['q1', 'q2', 'q1'], ['r1', 'r1', 'r2']] 

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

Объясните, как вы хотите сгруппировать эти строки.

Группа pandas по выражению не является самоочевидной.

Если я просто придавить data массив, я могу групповые последовательные значения и сосчитать их:

In [726]: data.ravel() 
Out[726]: 
array(['p1', 'p1', 'p2', 'q1', 'q2', 'q1', 'r1', 'r1', 'r2'], 
     dtype='<U2') 
In [727]: g=itertools.groupby(data.ravel()) 
In [728]: [(k,list(v)) for k,v in g] 
Out[728]: 
[('p1', ['p1', 'p1']), 
('p2', ['p2']), 
('q1', ['q1']), 
('q2', ['q2']), 
('q1', ['q1']), 
('r1', ['r1', 'r1']), 
('r2', ['r2'])] 
In [729]: g=itertools.groupby(data.ravel()) 
In [730]: [(k,len(list(v))) for k,v in g] 
Out[730]: [('p1', 2), ('p2', 1), ('q1', 1), ('q2', 1), ('q1', 1), ('r1', 2), ('r2', 1)] 

=============

Продление моего ответа на работу рядам

In [738]: grps = [itertools.groupby(row) for row in data] 
In [739]: [[(k, len(list(v))) for k,v in r] for r in grps] 
[[('p1', 2), ('p2', 1)], 
[('q1', 1), ('q2', 1), ('q1', 1)], 
[('r1', 2), ('r2', 1)]] 

Это работает для версии объекта recarray из data, а также.

К сожалению, я не понял ваше описание 'row-wise'. Даже перечитывая свой последний комментарий, я не понимаю, чего вы хотите. Это не похоже на проблему itertools.groupby. Я думал, вы считаете строки, такие как «r1» и «q2». По-видимому, это не так.

====================

КИ, более целенаправленная попытка воссоздать таблицу панда

Используйте itertools.product для создания 8 комбинаций эти 6 строк:

In [847]: pos = list(product(['r1','r2'],['p1','p2'],['q1','q2'])) 
In [848]: pos 
Out[848]: 
[('r1', 'p1', 'q1'), 
('r1', 'p1', 'q2'), 
('r1', 'p2', 'q1'), 
('r1', 'p2', 'q2'), 
('r2', 'p1', 'q1'), 
('r2', 'p1', 'q2'), 
('r2', 'p2', 'q1'), 
('r2', 'p2', 'q2')] 

преобразовать dataframe в список списков:

In [849]: val=data.values[:,[2,0,1]].tolist() 
In [850]: val 
Out[850]: [['r1', 'p1', 'q1'], ['r1', 'p1', 'q2'], ['r2', 'p2', 'q1']] 

фантастическом ой, какие из возможных комбинаций можно найти в vals:

In [852]: [[i, list(i) in val] for i in pos] 
Out[852]: 
[[('r1', 'p1', 'q1'), True], 
[('r1', 'p1', 'q2'), True], 
[('r1', 'p2', 'q1'), False], 
[('r1', 'p2', 'q2'), False], 
[('r2', 'p1', 'q1'), False], 
[('r2', 'p1', 'q2'), False], 
[('r2', 'p2', 'q1'), True], 
[('r2', 'p2', 'q2'), False]] 

переделки «рассчитывает» как 2x8 0/1 массива:

In [853]: np.array([[list(i) in val] for i in pos]).reshape(2,-1).astype(int) 
Out[853]: 
array([[1, 1, 0, 0], 
     [0, 0, 1, 0]]) 
+0

К сожалению там была опечатка. Я заменил «R»: ['q1', 'q2', 'q1'] на 'R': ['r1', 'r1', 'r2']. Группировка выполняется по ряду причин. Например, существует строка 'p1 q1 r1', и она встречается один раз, поэтому на выходе есть соответствующая ей. На выходе отображаются все возможные комбинации строк, которые могут возникнуть. Он отображает частоту этих комбинаций, если они существуют, и ноль, если они не используются. Здесь «p1 q1 r2» не существует, поэтому ему соответствует нуль. Я пытаюсь получить аналогичный результат, не используя pandas. Кроме того, вход должен быть структурированным массивом типа данных объекта. @hpaulj – geedee

+0

Пока неясно, чего вы хотите. Это не проблема 'recarray' или' itertools.groupby'. – hpaulj

+0

По строкам я имел в виду строки в dataframe, те, которые были на выходе. Итак, это строки, о которых я говорил - (p1 q1 r1), (p1 q2 r1) и (p2 q1 r2). Все, что я хотел, было результатом, подобным результату выше, без использования панд. itertools.groupby() был просто тем, что я пробовал, чтобы не тренироваться. Приносим извинения, если не ясно. Тем не менее, отличный ответ, я узнал что-то новое. Thanks- @hpaulj – geedee