首页 > 解决方案 > 在python中将一个字符串与同一列中的所有其他字符串进行比较

问题描述

我有一个看起来像这样的熊猫 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}})

我现在正在尝试执行以下操作。对于 column 下的每个值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']. 这意味着,在我的第一次迭代中(在哪里s1AACCTACG,我会将函数compare应用于同一列下的所有其他值,即AACCTACG带有TTGCGAGA、和。然后我会为第二行(现在是我的新值)做同样的事情,依此类推,直到我到达 下的最后一个条目。TTGCTTGGTACACACGTTCGGCTATTGCGAGAs1df['barcode_sequence']

到目前为止,我已经获得了每个条目所需的迭代次数df['barcode_sequence'],这可以通过将嵌套 for 循环与该iterrows()方法相结合来实现。所以如果我这样做:

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

我至少得到了我正在比较的字符串(我s1的 in compare)以及我将为每个字符串进行的比较次数s1

尽管我坚持s2为每个人提取所有内容s1

标签: pythonstringpandasfor-loop

解决方案


这是一种使用交叉连接格式的方法(不需要明确的 for 循环):

# 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

推荐阅读