сравнение одной строки со всеми остальными в одном столбце в python - PullRequest
1 голос
/ 26 февраля 2020

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

df = pd.DataFrame({'index': {0: 34, 1: 35, 2: 36, 3: 37, 4: 38},
 'lane': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1},
 'project': {0: 'default',
  1: 'default',
  2: 'default',
  3: 'default',
  4: 'default'},
 'sample': {0: 'None-BORD1778',
  1: 'None-BORD1779',
  2: 'None-BORD1780',
  3: 'None-BORD1782',
  4: 'None-BORD1783'},
 'barcode_sequence': {0: 'AACCTACG',
  1: 'TTGCGAGA',
  2: 'TTGCTTGG',
  3: 'TACACACG',
  4: 'TTCGGCTA'},
 'pf_clusters': {0: '"1,018,468"',
  1: '"750,563"',
  2: '"752,191"',
  3: '"876,957"',
  4: '"695,347"'},
 '%_of_the_lane': {0: 0.28, 1: 0.21, 2: 0.21, 3: 0.24, 4: 0.19},
 '%_perfect_barcode': {0: 100.0, 1: 100.0, 2: 100.0, 3: 100.0, 4: 100.0},
 'yield_(mbases)': {0: '511', 1: '377', 2: '378', 3: '440', 4: '349'},
 '%_pf_clusters': {0: 100.0, 1: 100.0, 2: 100.0, 3: 100.0, 4: 100.0},
 '%_>=_q30_bases': {0: 89.74, 1: 89.9, 2: 89.0, 3: 89.31, 4: 88.69},
 'mean_quality_score': {0: 35.13, 1: 35.15, 2: 34.98, 3: 35.04, 4: 34.92}})

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

Для этого я определил следующую функцию :

def compare(s1,s2):
    return len([x for x in range(len(s1)) if s1[x] == s2[x]])/len(s1)

Теперь я хочу применить эту функцию к каждому значению в df['barcode_sequence']. Это означает, что в моей первой итерации (где s1 равно AACCTACG) я бы применил функцию compare ко всем другим значениям в этом же столбце, т.е. AACCTACG с TTGCGAGA, TTGCTTGG, TACACACG и TTCGGCTA. Затем я делал бы то же самое для второй строки TTGCGAGA (которая теперь является моим новым значением s1) и так далее, пока не достигну окончательной записи в df['barcode_sequence'].

Пока я Я получил количество итераций, которое мне нужно для каждой записи в df['barcode_sequence'], что может быть достигнуто с помощью комбинации вложенных для l oop с помощью метода iterrows(). Поэтому, если я сделаю:

for index, row in df.iterrows():
    for sample in list(range(len(df.index))):
        print(index, row['sample'],row['barcode_sequence'])

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

Хотя я застрял в извлечении всех s2 для каждого s1

1 Ответ

1 голос
/ 26 февраля 2020

Вот способ сделать это с использованием формата перекрестного соединения (не требуется явного для циклов):

# do a cross join 
df1 = df[['barcode_sequence']].copy()
df1['barcode_un'] = [df1['barcode_sequence'].unique().tolist() for _ in range(df1.shape[0])]

# remove duplicate rows
df1 = df1.explode('barcode_un').query("barcode_sequence != barcode_un").reset_index(drop=True)

# calculate the score
df1['score'] = df1.apply(lambda x: compare(x['barcode_sequence'], x['barcode_un']), 1)

print(df1)

   barcode_sequence barcode_un  score
0          AACCTACG   TTGCGAGA  0.250
1          AACCTACG   TTGCTTGG  0.375
2          AACCTACG   TACACACG  0.625
3          AACCTACG   TTCGGCTA  0.125
4          TTGCGAGA   AACCTACG  0.250
5          TTGCGAGA   TTGCTTGG  0.625
6          TTGCGAGA   TACACACG  0.250
7          TTGCGAGA   TTCGGCTA  0.500
8          TTGCTTGG   AACCTACG  0.375
9          TTGCTTGG   TTGCGAGA  0.625
10         TTGCTTGG   TACACACG  0.250
11         TTGCTTGG   TTCGGCTA  0.250
12         TACACACG   AACCTACG  0.625
13         TACACACG   TTGCGAGA  0.250
14         TACACACG   TTGCTTGG  0.250
15         TACACACG   TTCGGCTA  0.250
16         TTCGGCTA   AACCTACG  0.125
17         TTCGGCTA   TTGCGAGA  0.500
18         TTCGGCTA   TTGCTTGG  0.250
19         TTCGGCTA   TACACACG  0.250
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...