Python Pandas Groupby и присоединиться - PullRequest
0 голосов
/ 28 сентября 2018

Я довольно новичок в python pandas и не могу найти ответ на мою проблему в каких-либо старых постах.

У меня есть простой фрейм данных, который выглядит примерно так:

dfA ={'stop':[1,2,3,4,5,1610,1611,1612,1613,1614,2915,...]
      'seq':[B, B, D, A, C, C, A, B, A, C, A,...] }

СейчасЯ хочу объединить значения 'seq' из каждой группы, где разница между следующим и предыдущим значением в 'stop' равна 1. Когда разница велика, например, 5 и 1610, именно здесь начинается следующий кластер, и таквкл.

Мне нужно записать все значения из каждого кластера в отдельные строки:

0 BBDAC   #join'stop' cluster 1-5  
1 CABAC   #join'stop' cluster 1610-1614

2 A....   #join'stop' cluster 2015 - ...
etc...

То, что я получаю с моим текущим кодом, выглядит так:

True   BDACABAC...
False  BCA...

для всего огромного фрейма данных.

Я понимаю логику, с которой он сливается, что соответствует указанному мною условию (не идеальное, потеря краев кластера), но у меня заканчиваются идеи, если яможно соединить его и правильно разделить на кластеры, а не на все строки кадра данных.

Пожалуйста, смотрите мой код ниже:

dfB = dfA.groupby((dfA.stop - dfA.stop.shift(1) == 1))['seq'].apply(lambda x: ''.join(x)).reset_index()

Пожалуйста, помогите.

PS Iтакже попробовал вариКомбинации с diff (), но это тоже не помогло.Я не уверен, хорош ли groupby для этого решения.Пожалуйста, порекомендуйте!

dfC = dfA.groupby((dfA['stop'].diff(periods=1)))['seq'].apply(lambda x: ''.join(x)).reset_index() 

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

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Я только что понял это.Мне удалось округлить значения «стоп» до ближайших 100 и назначить его в качестве нового столбца.Тогда мой предыдущий код работает .... Большое спасибо за быстрый ответ.

dfA ['new_val'] = (dfA ['stop'] / 100) .astype (int) * 100

0 голосов
/ 28 сентября 2018

Я думаю, вам нужно создать помощника Series для группировки:

g = dfA['stop'].diff().ne(1).cumsum()
dfC = dfA.groupby(g)['seq'].apply(''.join).reset_index()
print (dfC)
   stop    seq
0     1  BBDAC
1     2  CABAC
2     3      A

Подробности :

Сначала получите различия на diff:

print (dfA['stop'].diff())
0        NaN
1        1.0
2        1.0
3        1.0
4        1.0
5     1605.0
6        1.0
7        1.0
8        1.0
9        1.0
10    1301.0
Name: stop, dtype: float64

Сравнить по ne (!=) для первых значений групп:

print (dfA['stop'].diff().ne(1))
0      True
1     False
2     False
3     False
4     False
5      True
6     False
7     False
8     False
9     False
10     True
Name: stop, dtype: bool

В последний раз создавать группы по cumsum:

print (dfA['stop'].diff().ne(1).cumsum())
0     1
1     1
2     1
3     1
4     1
5     2
6     2
7     2
8     2
9     2
10    3
Name: stop, dtype: int32
...