Pandas как посчитать частоты паттернов в датафрейме - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть этот пример фрейма данных:

ID,Action,Station
01,P,S1
01,R,S2
01,P,S1
01,R,S2
02,P,S2
02,R,S1
02,P,S2
02,R,S1
03,P,S2
03,R,S1

Моя цель состоит в том, чтобы подсчитать количество вхождений в столбцах Action и Station, таких как упорядоченные пары, такие как (P, R) и соответствующие Station ценности. Таким образом, результирующий кадр данных будет иметь вид:

S1,S2,2
S2,S1,3

Таким образом, шаблон для поиска является кортежем (P, R) для каждого ID (значения ID могут дублироваться) и подсчитывается их частота в Station.

Мои попытки до сих пор сводились к групповке с помощью Action и Station, и они получают значения:

g = df.groupby(['Station','ID'])['Action'].size()

и получают:

Station  ID
S1       1     2
         2     2
         3     1
S2       1     2
         2     2
         3     1
Name: Action, dtype: int64

но все же я не могу позаботиться о (P, R) кортеже и его частотах.

Ответы [ 2 ]

2 голосов
/ 17 февраля 2020

Определить счетчик для пар строк внутри каждого идентификатора. Затем объедините P и R вместе, объединившись с собой, но отобразив P -> R и R -> P в один фрейм. Удалите дубликаты, так как вторая строка является избыточной, затем получите размер.

Это работает только потому, что каждый идентификатор имеет P и R, встречающиеся парами, один ряд за другим

df['idx'] = df.groupby('ID').cumcount()//2
m = (df.merge(df.assign(Action=df.Action.map({'P': 'R', 'R': 'P'})),
              on=['ID', 'idx', 'Action'], suffixes=['_P', '_R'])
       .drop_duplicates(['ID', 'idx']))

m.groupby(['Station_P', 'Station_R']).size()

Station_P  Station_R
S1         S2           2
S2         S1           3
dtype: int64

Для справки m выглядит как

   ID Action Station_P  idx Station_R
0   1      P        S1    0        S2
2   1      P        S1    1        S2
4   2      P        S2    0        S1
6   2      P        S2    1        S1
8   3      P        S2    0        S1
2 голосов
/ 17 февраля 2020

Один из способов - сгруппировать P,R по cumsum() и использовать cumcount:

(df.assign(order=df.Action.eq('P')
                   .groupby(df['ID'])  # this might not be necessary
                   .cumsum())
   .groupby(['ID', 'order'])
   .Station.agg(tuple)
   .groupby('ID').value_counts()
)

Выход:

ID  Station 
1   (S1, S2)    2
2   (S2, S1)    2
3   (S2, S1)    1
Name: Station, dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...