Pandas:从数据框匹配列到列表创建table

Pandas: Create table from data frame matching columns to a list

我正在尝试从数据框和列表创建矩阵。数据框的列表和第 1 列包含相同的字符串,但是,并非列表中的所有字符串都在第 1 列中并且顺序不同(请参见下面的示例)。我想搜索数据框,如果第 1 列中的字符串与列表中的字符串匹配,则在第二列中打印数据,否则在 seqList 和 0NaNmissing 等。我认为 pandas 对此有好处,因为我可以使用 df.equals 比较数据框中的列,但即使存在字符串,它也会报告 false并且应该匹配。

我认为这可能是因为我在 seqList 中的字符串比在数据框中的字符串多,而且它们的顺序不同。因此,我试图索引数据框,但我在第 2 列中的数据是 lost/replaced 和 NaN


列表

seqList = ['Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1', 'Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1', 'Cand_Eff_3_MAMSRFVVTLGLCVSASA_rc_1', 'Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1', 'Cand_Eff_5_MPVLQVVVVVVAMAVVKVVMV_rc_1']

数据帧的 Infile

#Infile2:

Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1   1
Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1    3
Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1    3

我想创建一个新矩阵,其中包含列表 (seqList) 中的所有序列和 infile2 中标识的出现次数。

期望输出

#outfile:
sequence    hits
Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1    3
Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1    1
Cand_Eff_3_MAMSRFVVTLGLCVSASA_rc_1    NaN
Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1    3
Cand_Eff_5_MPVLQVVVVVVAMAVVKVVMV_rc_1    NaN

我已将 infile2 作为数据框加载并命名为列:

#Create the dataframe from the sequnce hits in the genomes (identified in the occurances file).
Occurences=pd.read_csv(infile2, delimiter='\t', index_col=False)    #Read the input file as a tab separated dataframe.
pd.set_option("display.max_colwidth", None) #Ensure that the sequence names are not cut off.
Occurences.rename(columns = {list(Occurences)[0]: 'sequence'}, inplace = True) #Name the sequences column
Occurences.rename(columns = {list(Occurences)[1]: 'hits'}, inplace = True) #Name the occurences column

我尝试将 seqList 转换为数据框,然后使用 .equals (as shown here) 但这仍然将匹配报告为 false:

SeqDataFrame= pd.DataFrame (seqList, columns = ['sequence']) #Load seqList as df
result = SeqDataFrame['sequence'].equals(Occurences['sequence'])  #Use .equals to compare the sequence columns and report matching
print(result)
False

我认为问题在于出现的 df 中序列列中的字符串顺序与 seqList 的顺序不同。因此,我尝试使用 seqList 索引出现数据框,但这似乎丢失了命中列中的所有数据。

Occurences.set_index('sequence', inplace=True)
Occurences = Occurences.reindex(seqList)
print(Occurences)
                                                                             
    hits
sequence                                                                                  
Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1                                                      NaN
Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1                                                     NaN
Cand_Eff_3_MAMSRFVVTLGLCVSASA_rc_1                                                     NaN
Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1                                                  NaN
Cand_Eff_5_MPVLQVVVVVVAMAVVKVVMV_rc_1                                                  NaN

我找过类似的问题,但 none 似乎有列顺序不匹配的问题。如果这是一个专门关于列不匹配的问题,他们会像我一样重新编制索引并且没有丢失数据。如何创建我想要的矩阵,其中包含 seqList 中的所有序列和 Occurences 数据框中标识的命中数?

非常感谢


n.b。我也曾尝试使用 pd.merge 来合并列表和数据框,但出于某种原因,这会创建一个空数据框:

MergedFrames = pd.merge(SeqDataFrame, Occurences, left_on=["sequence"], right_on=['sequence'])
print("MergedFrames")
print(MergedFrames)

MergedFrames
Empty DataFrame
Columns: [sequence, hits]
Index: []

您可以使用 DataFrame.reindex:

Occurences.set_index('sequence').reindex(seqList).reset_index()
                                sequence  hits
0      Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1   3.0
1     Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1   1.0
2     Cand_Eff_3_MAMSRFVVTLGLCVSASA_rc_1   NaN
3  Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1   3.0
4  Cand_Eff_5_MPVLQVVVVVVAMAVVKVVMV_rc_1   NaN

如果您的列表可以重复,只需使用 list(set(seqList))

假设一个元素在seqList中可以出现多次:

seqDF = pd.DataFrame({'results': seqList})
df = pd.DataFrame({'diag': ['Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1', 'Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1','Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1'],
                 'occ': [1, 3, 3]})
mergeDF = seqDF.merge(df, how='left', left_on='results', right_on='diag')
mergeDF[['results', 'occ']].groupby('results')[['occ']].sum()

给出:

Cand_Eff_1_MLAELSVAFTLAAFALA_rc_1   3.0
Cand_Eff_2_MTRFHLILLPLLFSWFSYCFG_1  1.0
Cand_Eff_3_MAMSRFVVTLGLCVSASA_rc_1  0.0
Cand_Eff_4_MAPYSMVLLGALSILGFGAYA_rc_1   3.0
Cand_Eff_5_MPVLQVVVVVVAMAVVKVVMV_rc_1   0.0

因为你想要出现的次数,我假设 0.0 比 NaN 更连贯