首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pandas df:添加列如果不存在,则从dict向新列添加值

pandas df:添加列如果不存在,则从dict向新列添加值
EN

Stack Overflow用户
提问于 2018-07-27 03:44:03
回答 2查看 2.9K关注 0票数 3

我刚接触pandas,但我正在尝试创建一个大型数据帧,其中我通过序列ID (Seq_ID)组织有关大量序列的信息,并将有关序列的信息添加到数据帧中。目前,df看起来像这样:

代码语言:javascript
复制
     Seq_ID        mol_type
0 4_cDNA_v              RNA
1 2_133+_v              RNA
2 5_BM4D_g              RNA
.                         .
.                         .
1301 4_PB_g             RNA

我想写一个函数来查看我当前的df,source_df,如果'Seq_source‘列不存在,它就会添加它。然后,为了填充“Source”列,我有一系列名为cell_type的键:值对。我想搜索Seq_ID列,看看是否在Seq_ID中找到了任何值,如果找到了,则将键添加到新列'Seq_Source‘的相应行中,使其如下所示:

代码语言:javascript
复制
     Seq_ID    mol_type    Seq_Source
0 4_cDNA_v          RNA            PB
1 2_133+_v          RNA          HSPC
2 5_BM4D_g          RNA          BMMC
.                     
.                     
1301 4_CD4_g        RNA          PBMC

我写了一些伪代码来帮助解释我对一种方法的想法。

代码语言:javascript
复制
cell_type = {
    'PBMC':['CD4','NK', 'CD8'],
    'HSPC': ['133+', '133+F'],
    'PB': ['cDNA', 'cDNAA', 'cDNAB', 'cDNAC'],
    'BMMC':['cDNABM', '34D_Vc','BM4_Vs', 'BM4_Vc', 'BM4n_Vs']
        }


def find_cell_source(dictionary, df, reference, new_header):
    '''
    takes in a dictionary where key corresponds to list of values.
    If new_header does not exist, the new column is created.
    If a value from key:value pair is found within any of the string entries under reference column
    in the database, key is added to reference row under new_header.
    '''

    # add new_header if does not exist
    df[new_header] = [df[new_header] if new_header not in df]

    # read rows of reference column and see if values from dict is in references
    # add key to row under new_header if it exists, pass if it doesn't

    for i in df['reference']:
        for k,v in dictionary:
            for j in v:
                if j in i:
                    df['new_header'] = k
                else:
                    pass
    return df


find_cell_source(cell_type, source_df, 'Seq_ID', 'Seq_Source')
EN

回答 2

Stack Overflow用户

发布于 2018-07-27 04:02:02

您可以通过各种方式获取Seq_ID的相关部分,在这种情况下,您似乎可以只使用.str.split,然后映射值。如果在_上拆分还不够,可以使用regex

代码语言:javascript
复制
d = dict((k,v) for v, x in cell_type.items() for k in x)
df['Seq_Source'] = df.Seq_ID.str.split('_', expand=True)[1].map(d)

输出:

代码语言:javascript
复制
        Seq_ID mol_type Seq_Source
0     4_cDNA_v      RNA         PB
1     2_133+_v      RNA       HSPC
2     5_BM4D_g      RNA        NaN
1301   4_CD4_g      RNA       PBMC

请注意,由于BM4D不在cell_type中的任何列表中,因此它被映射到NaN

票数 2
EN

Stack Overflow用户

发布于 2018-07-27 04:03:10

每当您发现自己必须频繁地查找值来恢复密钥时,通常最好重塑字典以允许您按键查找,这样效率更高。

假设内部列表中的所有值都是唯一的,您可以使用以下代码片段重塑查找字典:

代码语言:javascript
复制
cell_type_reshaped = {}

for k, v in cell_type.items():
    for element in v:
        cell_type_reshaped[element] = k

给予:

代码语言:javascript
复制
{'133+': 'HSPC',
 '133+F': 'HSPC',
 '34D_Vc': 'BMMC',
 'BM4_Vc': 'BMMC',
 'BM4_Vs': 'BMMC',
 'BM4n_Vs': 'BMMC',
 'CD4': 'PBMC',
 'CD8': 'PBMC',
 'NK': 'PBMC',
 'cDNA': 'PB',
 'cDNAA': 'PB',
 'cDNAB': 'PB',
 'cDNABM': 'BMMC',
 'cDNAC': 'PB'}

创建一个用于测试的小DataFrame:

代码语言:javascript
复制
df = pd.DataFrame(data=[['4_cDNA_v', 'RNA'], ['2_133+_v', 'RNA'], 
                        ['5_BM4D_g', 'RNA']], columns=['Seq_ID', 'mol_type'])

从这里看,这只是一个使用Pandas map函数查找字典的例子。注意,这里有一个额外的步骤,它对Seq_ID进行切片,以获得字符串的倒数第三个字符和倒数第三个字符,这似乎就是它们所遵循的模式。如果不是这样,请让我知道,我可以更新。

代码语言:javascript
复制
df['Seq_Source'] = df['Seq_ID'].str.slice(2, -2).map(cell_type_reshaped)

给出我认为至少接近你想要的结果:

代码语言:javascript
复制
     Seq_ID mol_type Seq_Source
0  4_cDNA_v      RNA         PB
1  2_133+_v      RNA       HSPC
2  5_BM4D_g      RNA        NaN

在你的例子中,我看到你有5_BM4D_g到BMMC的映射,我不确定这背后的逻辑,所以请评论一下,我可以更新。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51546445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档