我刚接触pandas,但我正在尝试创建一个大型数据帧,其中我通过序列ID (Seq_ID)组织有关大量序列的信息,并将有关序列的信息添加到数据帧中。目前,df看起来像这样:
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‘的相应行中,使其如下所示:
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我写了一些伪代码来帮助解释我对一种方法的想法。
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')发布于 2018-07-27 04:02:02
您可以通过各种方式获取Seq_ID的相关部分,在这种情况下,您似乎可以只使用.str.split,然后映射值。如果在_上拆分还不够,可以使用regex
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)输出:
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
发布于 2018-07-27 04:03:10
每当您发现自己必须频繁地查找值来恢复密钥时,通常最好重塑字典以允许您按键查找,这样效率更高。
假设内部列表中的所有值都是唯一的,您可以使用以下代码片段重塑查找字典:
cell_type_reshaped = {}
for k, v in cell_type.items():
for element in v:
cell_type_reshaped[element] = k给予:
{'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:
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进行切片,以获得字符串的倒数第三个字符和倒数第三个字符,这似乎就是它们所遵循的模式。如果不是这样,请让我知道,我可以更新。
df['Seq_Source'] = df['Seq_ID'].str.slice(2, -2).map(cell_type_reshaped)给出我认为至少接近你想要的结果:
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的映射,我不确定这背后的逻辑,所以请评论一下,我可以更新。
https://stackoverflow.com/questions/51546445
复制相似问题