如何使用来自另一个数据框的部分匹配来过滤数据框

How to filter a dataframe using partial matches from another dataframe

我有两个数据框,我想使用其中一个数据框来过滤另一个数据框并制作一个新的数据框。这两个数据框有一列信息相似,但并不完全匹配。我一直在尝试使用 str.contains,但到目前为止,当我尝试时,我一直在使用 TypeError: 'Series' objects are mutable, thus they cannot be hashed。这是我的数据帧示例和我尝试过的代码。

promoter = pd.read_csv('promoter_coordinate.csv')
print(promoter.head())

AssociatedGeneName            B      C    D E                                   F
            plexB_1  NC_004353.3  64381  - Drosophila melanogaster (Fruit fly)  region 
               ci_1  NC_004353.3  76925  - Drosophila melanogaster (Fruit fly)  region   
             RS3A_1  NC_004353.3  87829  - Drosophila melanogaster (Fruit fly)  region   
              pan_1  NC_004353.3  89986  + Drosophila melanogaster (Fruit fly)  region  
              pan_2  NC_004353.3  90281  + Drosophila melanogaster (Fruit fly)  region   

data = pd.read_csv('FBgn with gene name.csv')
print(data.head())
Gene AssociatedGeneName   FBgn Number     timepoint
CG10002        fkh        FBgn0000659          2   
CG10002        fkh        FBgn0000659          2   
CG10002        fkh        FBgn0000659          2   
CG10002        fkh        FBgn0000659          2   
CG10006    CG10006        FBgn0036461          2   

x = promoter[promoter['AssociatedGeneName'].str.contains(data['AssociatedGeneName'])]

两个列表的头部都不匹配,但基本上理想的结果类似于以下内容,其中将比较名为 'AssociatedGeneName' 的两列。

AssociatedGeneName            B      C    D  E                                    F    
             fkh_1  NT_033777.2  24410805 -  Drosophila melanogaster (Fruit fly)  region

本质上,我想要一个数据框,其中包含 promoter 中的所有值,这些值与 data['AssociatedGeneName'] 中的值部分匹配 如果有人能指出正确的方向,我将不胜感激。我对编码比较陌生,我一直在使用 python 和 pandas,并且更愿意继续使用 python 来解决这个问题。这是我不断收到的错误。

x = promoter[promoter['AssociatedGeneName'].str.contains(data['AssociatedGeneName'])]

Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    x = promoter[promoter['AssociatedGeneName'].str.contains(data['Associated Gene Name'])]
  File "C:\Python34\lib\site-packages\pandas\core\strings.py", line 1226, in contains
na=na, regex=regex)
  File "C:\Python34\lib\site-packages\pandas\core\strings.py", line 203, in str_contains
regex = re.compile(pat, flags=flags)
  File "C:\Python34\lib\re.py", line 219, in compile
return _compile(pattern, flags)
  File "C:\Python34\lib\re.py", line 278, in _compile
return _cache[type(pattern), pattern, flags]
  File "C:\Python34\lib\site-packages\pandas\core\generic.py", line 663, in __hash__
    ' hashed'.format(self.__class__.__name__))
TypeError: 'Series' objects are mutable, thus they cannot be hashed

str.contains 接受一个字符串作为参数并检查该字符串是否包含在每个 promoter.AssociatedGene 条目中,然后 returns TrueFalse 每个索引(行)。

但是,当您将 data.AssociatedGene 传递给 str.contains 函数时,您传递的是 pandas.Series,这就是您收到错误的原因。

如果您只想要启动子部分匹配的行,那么您可以

where_inds_par = [ where(promoter.AssociatedGeneName.str.contains(partial) )[0] for partial in data.AssociatedGeneName  ]

现在,where_inds_par 的每个元素本身就是一个长度为 >= 0 的索引数组。此外,会有一些冗余,因为您的 data.AssociatedGeneName 列是多余的,但是您可以使用 set 和一些花哨的列表理解来过滤掉它

inds_par = list(set( i for sublist in where_inds_par for i in sublist )) # set finds the unique elements
promoter_par = promoter.ix[ promoter.index[ inds_par], ]

首先创建一个函数来检查 promoter 中的值是否与 data 中的值部分匹配,这将检查 data

中的每个值
def contain_partial(x , y = data.AssociatedGeneName):
        res = []
        for z in y:
            res.append(z in x)
        return res

这将是函数的结果

contains = promoter.AssociatedGeneName.apply(contain_partial)

然后在最后检查是否至少有一个值是 true 然后 return true 和过滤器 promoter

promoter[contains.apply(any)]