【问题标题】:How to extract first occurance of the data within the delimiter based on keyvalues?如何根据键值提取分隔符内第一次出现的数据?
【发布时间】:2020-06-07 21:59:40
【问题描述】:

我有一个如下的数据框:

Items   Data
enst.35 abc|frame|gtk|enst.24|pc|hg|,abc|framex|gtk4|enst.35|pxc|h5g|,abc|frbx|hgk4|enst.23|pix|hoxg|,abc|framex|gtk4|enst.35|pxc|h5g|
enst.18 abc|frame|gtk|enst.15|pc|hg|,abc|framex|gtk2|enst.59|pxc|h5g|,abc|frbx|hgk4|enst.18|pif|holg|,abc|framex|gtk4|enst.35|pxc|h5g|
enst.98 abc|frame|gtk|enst.98|pc|hg|,abc|framex|gtk1|enst.45|pxc|h5g|,abc|frbx|hgk4|enst.74|pig|ho6g|,abc|framex|gtk4|enst.35|pxc|h5g|
enst.63 abc|frame|gtk|enst.34|pc|hg|,abc|framex|gtk1|enst.67|pxc|h5g|,abc|frbx|hgk4|enst.39|pik|horg|,abc|framex|

我想根据框架内的Items 值提取Data,并仅提取分隔符(,) 中的数据。我想将 col1 的 row1 值与 col2 的 row1 匹配。同理,col1 的 row2 到 col2 的 row2....

如果未找到匹配项,则在输出列中填充“NA”。同一列中可以有多个 id 出现,但我只想考虑第一次出现。

预期的输出是:

abc|framex|gtk4|enst.35|pxc|h5g|
abc|frbx|hgk4|enst.18|pif|homg|
abc|frame|gtk|enst.98|pc|hg|
NA

我尝试了以下代码来生成输出:

import pandas as pd
df=pd.read_table('file1.txt', sep="\t")
keywords=df['Items'].to_list()
df_map=df.Data[df.Data.str.contains('|'.join(as_list))].reindex(df.index)

但生成的输出中包含包含关键字的所有术语:

Data
abc|frame|gtk|enst.24|pc|hg|,abc|framex|gtk4|enst.35|pxc|h5g|,abc|frbx|hgk4|enst.23|pix|hoxg|abc|framex|gtk4|enst.35|pxc|h5g|
abc|frame|gtk|enst.15|pc|hg|,abc|framex|gtk2|enst.59|pxc|h5g|,abc|frbx|hgk4|enst.18|pif|holg|abc|framex|gtk4|enst.35|pxc|h5g|
abc|frame|gtk|enst.98|pc|hg|,abc|framex|gtk1|enst.45|pxc|h5g|,abc|frbx|hgk4|enst.74|pig|ho6g|abc|framex|gtk4|enst.35|pxc|h5g|
NA

我可以对代码进行哪些更改以按预期生成正确的输出。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    axis=1 旁边使用DataFrame.apply 并应用自定义函数,该函数提取与df['Data'] 中出现df['Items'] 相关的字符串:

    import re
    
    def find(s):
        mobj = re.search(rf"[^,]+{re.escape(s['Items'])}[^,]+", s['Data'])
        if mobj:
            return mobj.group(0)
        return np.nan
    
    df['Data'] = df.apply(find, axis=1)
    

    或者,使用更快的解决方案:

    pattern = '|'.join([rf'[^,]+{re.escape(k)}[^,]+'for k in df['Items']])
    df['Data'] = df['Data'].str.findall(pattern).str.get(0)
    

    # print(df['Data'])
    
    0    abc|framex|gtk4|enst.35|pxc|h5g|
    1     abc|frbx|hgk4|enst.18|pif|holg|
    2        abc|frame|gtk|enst.98|pc|hg|
    3                                 NaN
    Name: Data, dtype: object
    

    【讨论】:

      【解决方案2】:

      我们可以正式定义一个键值对列表如下:

      kvlist = <key>[kvdelim]<value>([pairdelim]<key>[kvdelim]<value>)*
      key = <string>|<quoter><string><quoter>
      value = <string>|<quoter><string><quoter>
      quoter = "
      

      【讨论】:

      • 我不是编码专家。能不能对我的代码做相应的修改,按要求生成输出
      猜你喜欢
      • 1970-01-01
      • 2014-03-22
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      • 2021-01-29
      相关资源
      最近更新 更多