我是熊猫新手,但是我试图创建一个大型数据框,在其中我通过其序列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”列不存在,则将其添加。 然后填写“ Seq_Source”列,我有一系列称为cell_type的key:value对。我想搜索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')
答案 0 :(得分:2)
您可以通过各种方式获取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
答案 1 :(得分:2)
每当您发现自己经常需要查找一个值以恢复密钥时,通常最好重塑该词典以允许您通过密钥进行查找,这更有效。
假设内部列表中的所有值都是唯一的,则可以使用以下代码段重塑查找字典:
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地图功能查找字典的一种情况。请注意,这里还有一个附加步骤,可对Seq_ID进行切片,以从包含字符串的最后一个字符开始将第3个字符转换为第3个字符,这似乎是它们遵循的模式。如果不是这种情况,请告诉我,我可以进行更新。
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
在您的示例中,我看到您有到BMMC的5_BM4D_g映射,我不确定其背后的逻辑,因此请发表评论,我可以进行更新。