#pandas #combinations
#pandas #комбинации
Вопрос:
У меня есть последовательности ДНК разных бактерий разной длины, которые представлены в строковом формате. Пример:
DNA
xx345- b324- c82- d13- c14
xx345- a22- c14- d13
a34- f12 - r27- fg98 - tr12
z23
xx345
Я хотел бы подсчитать совпадения каждого фрагмента ДНК в моем наборе данных. Мне нужны два вывода. Первый:
pair
xx345- b324
xx345- c82
xx345- d13
xx345- a22
xx345- c14
xx345- c14
b324- c82
b324- d13
b324- c14
c82- d13
c82- c14
d13- c14
d13- c14
a22- c14
a22- d13
a34- f12
a34- r27
a34- fg98
a34- tr12
f12- r27
f12- fg98
f12- tr12
r27- fg98
r27- tr12
fg98- tr12
z23
xx345
Затем
pair count
xx345- b324 1
xx345- c82 1
xx345- d13 1
xx345- a22 1
xx345- c14 2
b324- c82 1
b324- d13 1
b324- c14 1
c82- d13 1
c82- c14 1
d13- c14 2
a22- c14 1
a22- d13 1
a34- f12 1
a34- r27 1
a34- fg98 1
a34- tr12 1
f12- r27 1
f12- fg98 1
f12- tr12 1
r27- fg98 1
r27- tr12 1
fg98- tr12 1
z23 1
xx345 1
Ответ №1:
Я считаю, что вам нужно разделить значения на s*-s*
— здесь s*
означает ноль или более пробелов, затем сгладить в понимании списка все комбинации:
from itertools import combinations
L = ['-'.join(y) for x in df['DNA'].str.split('s*-s*') for y in combinations(x, 2)]
При необходимости сортировка значений:
L = ['-'.join(sorted(y)) for x in df['DNA'].str.split('s*-s*')
for y in combinations(x, 2)]
Последний переход к Series
и вызов Series.value_counts
:
s = pd.Series(L)
print (s)
0 xx345-b324
1 xx345-c82
2 xx345-d13
3 xx345-c14
4 b324-c82
5 b324-d13
6 b324-c14
7 c82-d13
8 c82-c14
9 d13-c14
10 xx345-a22
11 xx345-c14
12 xx345-d13
13 a22-c14
14 a22-d13
15 c14-d13
16 a34-f12
17 a34-r27
18 a34-fg98
19 a34-tr12
20 f12-r27
21 f12-fg98
22 f12-tr12
23 r27-fg98
24 r27-tr12
25 fg98-tr12
dtype: object
s1 = s.value_counts()
print (s1)
xx345-c14 2
xx345-d13 2
c14-d13 1
f12-tr12 1
xx345-a22 1
a34-fg98 1
f12-r27 1
a34-r27 1
c82-c14 1
f12-fg98 1
a22-c14 1
a34-tr12 1
a34-f12 1
b324-d13 1
r27-tr12 1
xx345-c82 1
d13-c14 1
b324-c14 1
xx345-b324 1
r27-fg98 1
fg98-tr12 1
b324-c82 1
c82-d13 1
a22-d13 1
dtype: int64
Редактировать:
from itertools import combinations
L = []
for x in df['DNA'].str.split('s*-s*'):
if len(x) > 1:
for y in combinations(x, 2):
L.append('-'.join(sorted(y)))
else:
L.append(x[0])
s = pd.Series(L)
print (s)
Комментарии:
1. Извините, есть также вирусы с одним элементом, вы не возражаете, если я обновлю вопрос?