Bohrium
robot
新建

空间站广场

论文
Notebooks
比赛
课程
Apps
我的主页
我的Notebooks
我的论文库
我的足迹

我的工作空间

任务
节点
文件
数据集
镜像
项目
数据库
公开
新手向-药物研发中的常见数据处理方法
机器学习
数据集
数据处理
中文
机器学习数据集数据处理中文
huangx@dp.tech
发布于 2023-09-25
推荐镜像 :Basic Image:bohrium-notebook:2023-04-07
推荐机型 :c2_m4_cpu
赞 3
1
2
新手向-药物研发中的常见数据处理方法与代码实践
引言
本教程中涉及到的工作流程
1. 加载数据
2. 数据清洗
2.1 基础清洗
2.2 简单数据处理 - 寻找最强效的COX2抑制剂
可以思考的小问题
2.3 高级清理
讨论
2.4 可视化 IC50 值
2.5 IC50 vs. Ki 相关系数
2.6 清洗化学结构
3. 输出数据集

新手向-药物研发中的常见数据处理方法与代码实践

©️ Copyright 2023 @ Authors
作者: 黄逍 📨
日期:2023-09-25
共享协议:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
快速开始:点击上方的 开始连接 按钮,选择 基础 notebook镜像及任意CPU节点配置,稍等片刻即可运行。

代码
文本

引言

在药物研发领域,数据集的重要性不言而喻。但是,尽管市场上存在大量的数据集,其质量却参差不齐。高质量的数据是研究成功的关键,但很多时候研究者们会遇到各种数据问题,如缺失数据、噪声过多或结构混乱等。这就使得数据处理和清洗变得尤为关键。一个合理处理且信息丰富的数据集不仅可以提高研究的准确性,也能为后续的研究提供有力支持。

在本教程中,我们将学习如何从ChEMBL数据库下载和处理数据。读完教程后,你应该熟悉数据结构,简单的数据分析,并了解与分子数据集相关的挑战。一个干净且信息丰富的数据集可以用于许多化学信息学任务,如相似性搜索、聚类或机器学习。

代码
文本

本教程中涉及到的工作流程

  1. 加载数据

  2. 数据清洗 2.1 基本清洗
    2.2 简单数据处理
    2.3 高级清洗
    2.4 可视化IC50值
    2.5 IC50与Ki的相关性
    2.6 清洗化学结构

  3. 导出数据

代码
文本

1. 加载数据

代码
文本

在这个教程中,我们将关注环氧酶-2 (COX-2) 的配体,这是抗炎药的一个重要药物靶点。例如,像阿司匹林、扑热息痛和布洛芬这样的日常和广泛开处方的药物都针对环氧酶。

代码
文本

首先,我们导入可能有用的Python库。

代码
文本
[11]
import math
import statistics
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
代码
文本

从ChEMBL数据库下载数据有几种方法。详细教程请参考这里。一种可能性是直接使用HTML GET请求访问API。我们可以如下所述直接使用Python来完成这个操作。这使得ChEMBL可以直接集成到你的工作流中,并允许你自定义想要检索的数据内容。然而,对于像COX2这样研究得很透彻的目标来说,这样的请求相对较慢。因此,下面的代码仅供你参考。

代码
文本
[12]
# design a python API for retrieving data from ChEMBL
import requests
def retrieve_data(target,limit=500):
url_stem = "https://www.ebi.ac.uk"
url_full_string = url_stem + "/chembl/api/data/activity.json?target_chembl_id__in=" + target + "&limit=" + str(limit)
url_full = requests.get( url_full_string ).json()
url_activities = url_full['activities']
while url_full['page_meta']['next']:
url_full = requests.get(url_stem + url_full['page_meta']['next']).json()
url_activities = url_activities + url_full['activities']
return pd.DataFrame(url_activities)
代码
文本

在这个教程中,为了确保每个人都能访问相同的数据集,我们将使用我们提供的数据文件。

代码
文本

下载完文件后,你可以导入并将其转化为Pandas的DataFrame,这是一个用于数据操作和分析的便捷数据结构。

Pandas有内置的 functions 可以读取各种格式的文件。

注意,你可能需要仔细选择特殊字符,如"注释"、"引号"和"换行符",以确保SMILES字符串和数据库的其他部分没有歧义。

代码
文本
[23]
import pandas as pd

# 直接从链接读取数据为pandas dataframe
data_url = "https://file.notion.so/f/f/c0d2f584-6fd0-41b1-82d4-7e7c74d40028/f77c1eb3-be40-4fbf-8231-242e91c05453/ChEMBL_COX-2.csv?id=b11a4ed5-eed9-4578-95e9-9b8fe9807149&table=block&spaceId=c0d2f584-6fd0-41b1-82d4-7e7c74d40028&expirationTimestamp=1695708000000&signature=Lx-Te5xbP49YtBBAkfUv7dOfJ-bafHgzACx6-2sV5Yw&downloadName=ChEMBL_COX-2.csv"
data = pd.read_csv(data_url)

# 查看dataframe的前几行
data.head()

Unnamed: 0 activity_comment activity_id activity_properties assay_chembl_id assay_description assay_type assay_variant_accession assay_variant_mutation bao_endpoint ... target_organism target_pref_name target_tax_id text_value toid type units uo_units upper_value value
0 0 NaN 34205 [] CHEMBL762912 In vitro inhibitory activity against human pro... B NaN NaN BAO_0000190 ... Homo sapiens Cyclooxygenase-2 9606 NaN NaN IC50 uM UO_0000065 NaN 0.06
1 1 NaN 34209 [] CHEMBL762912 In vitro inhibitory activity against human pro... B NaN NaN BAO_0000190 ... Homo sapiens Cyclooxygenase-2 9606 NaN NaN IC50 uM UO_0000065 NaN 3.23
2 2 NaN 35476 [] CHEMBL762912 In vitro inhibitory activity against human pro... B NaN NaN BAO_0000190 ... Homo sapiens Cyclooxygenase-2 9606 NaN NaN IC50 uM UO_0000065 NaN 0.08
3 3 NaN 36218 [] CHEMBL769655 Tested in vitro for inhibition against Prostag... B NaN NaN BAO_0000190 ... Homo sapiens Cyclooxygenase-2 9606 NaN NaN IC50 nM UO_0000065 NaN 0.12
4 4 NaN 36708 [] CHEMBL762912 In vitro inhibitory activity against human pro... B NaN NaN BAO_0000190 ... Homo sapiens Cyclooxygenase-2 9606 NaN NaN IC50 uM UO_0000065 NaN 100.00

5 rows × 46 columns

代码
文本

2. 数据清洗

代码
文本

2.1 基础清洗

代码
文本

虽然我们已经有了一个包含多个记录的数据集,但它可能包含许多不必要的甚至是错误的信息。因此,在我们开始分析数据集并从中得出任何结论之前,我们首先需要对其进行"清洗"。

现在,让我们进行数据过滤,只考虑:

  • 结合数据(试验类型 assay_type "B"
  • 精确测量(关系 relation "="
  • 标准的生物活性类型(standard_type为 "IC50", "Ki""Inhibition"

对于每个记录,我们只保留感兴趣的特征。

代码
文本
[24]
# keep entries with available IC50, Ki and Inhibition values, and only keep necessary information

activity = data.loc[(data['assay_type'] == 'B') &
(data['relation'] == '=') &
(data['standard_type'].isin(["IC50", 'Ki', 'Inhibition']))].copy() # add in more filtering keywords as necessary


activity = activity[["activity_id",
"assay_chembl_id",
"assay_description",
"assay_type",
"canonical_smiles",
"molecule_chembl_id",
"standard_type",
"standard_units",
"standard_value",
"pchembl_value",
"target_chembl_id",
"target_organism"]]

print("There are {} entries." .format(activity.shape[0]))
activity.head() # display first 5 entries
There are 7530 entries.
activity_id assay_chembl_id assay_description assay_type canonical_smiles molecule_chembl_id standard_type standard_units standard_value pchembl_value target_chembl_id target_organism
0 34205 CHEMBL762912 In vitro inhibitory activity against human pro... B Cc1ccc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccccc1 CHEMBL297008 IC50 nM 60.00 7.22 CHEMBL230 Homo sapiens
1 34209 CHEMBL762912 In vitro inhibitory activity against human pro... B Cc1c(C=O)cc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccc(F)cc1 CHEMBL289813 IC50 nM 3230.00 5.49 CHEMBL230 Homo sapiens
2 35476 CHEMBL762912 In vitro inhibitory activity against human pro... B Cc1c(COc2cccc(Cl)c2)cc(-c2ccc(S(C)(=O)=O)cc2)n... CHEMBL43736 IC50 nM 80.00 7.10 CHEMBL230 Homo sapiens
3 36218 CHEMBL769655 Tested in vitro for inhibition against Prostag... B Fc1ccc(-c2[nH]c(-c3ccc(F)cc3)c3c2C2CCC3CC2)cc1 CHEMBL140167 IC50 nM 0.12 9.92 CHEMBL230 Homo sapiens
5 39073 CHEMBL762912 In vitro inhibitory activity against human pro... B CC(=O)c1cc(-c2ccc(S(C)(=O)=O)cc2)n(-c2ccc(F)cc... CHEMBL44290 IC50 nM 1610.00 5.79 CHEMBL230 Homo sapiens
代码
文本

为了了解生物活性类型的组成,我们可以生成柱状图来可视化每种生物活性类型(IC50,Ki,Inhibition)的条目数量。

你可以使用matplotlib.pyplot.bar函数。请正确标记你的坐标轴。

代码
文本
[28]
# generate bar plot

def count_entry():
count = []
for i in range(len(activity['standard_type'].unique())):
count.append((activity['standard_type'] == [x for x in activity['standard_type'].unique()][i]).sum())
return count

plt.bar(activity['standard_type'].unique(), count_entry())
plt.xlabel('bioactivity type')
plt.ylabel('entry numbers')
plt.show()
print('IC50有{}条记录, Inhibition有{}条记录, Ki有{}条记录。'.format(entries[0], entries[1], entries[2]))
代码
文本

在教程的后续部分,我们将对数据进行一系列数学计算,因此检查并确保数据类型是兼容的非常重要,或者看是否需要将列转换为其他数据类型。

代码
文本
[29]
activity.dtypes # check datatype
activity_id             int64
assay_chembl_id        object
assay_description      object
assay_type             object
canonical_smiles       object
molecule_chembl_id     object
standard_type          object
standard_units         object
standard_value        float64
pchembl_value         float64
target_chembl_id       object
target_organism        object
dtype: object
代码
文本

2.2 简单数据处理 - 寻找最强效的COX2抑制剂

代码
文本

既然我们已经下载了COX-2的IC50数据并确保Python将其识别为数字,那么让我们尝试找出最已知的最强效的COX-2抑制剂是什么。按照升序对所有IC50值进行排序,并尝试找到最小的IC50值(即最强效的化合物)。

代码
文本
[30]
# please write your code below

ic50_rank = activity.loc[(activity['standard_type'] == 'IC50')].copy()
ic50_rank.sort_values('standard_value', ascending = True).head()
activity_id assay_chembl_id assay_description assay_type canonical_smiles molecule_chembl_id standard_type standard_units standard_value pchembl_value target_chembl_id target_organism
8491 12072259 CHEMBL2161532 Inhibition of human recombinant COX2 expressed... B CC(Oc1cc(=O)oc2ccccc12)C(=O)N1CCCC1 CHEMBL2158361 IC50 nM 0.0 NaN CHEMBL230 Homo sapiens
4721 2233024 CHEMBL969894 Inhibition of human COX2 B O=C(O)CCCC[C@@H]1CCSS1 CHEMBL134342 IC50 nM 0.0 NaN CHEMBL230 Homo sapiens
4722 2233025 CHEMBL969894 Inhibition of human COX2 B O=c1c2ccccc2[se]n1-c1ccccc1 CHEMBL51085 IC50 nM 0.0 NaN CHEMBL230 Homo sapiens
4724 2233027 CHEMBL969894 Inhibition of human COX2 B Clc1ccc(-c2cn[se]c2-c2ccc(Cl)cc2)cc1 CHEMBL501676 IC50 nM 0.0 NaN CHEMBL230 Homo sapiens
4725 2233028 CHEMBL969894 Inhibition of human COX2 B Cc1ccc(-c2[se]ncc2-c2ccc(Cl)cc2)cc1 CHEMBL471171 IC50 nM 0.0 NaN CHEMBL230 Homo sapiens
代码
文本

可以思考的小问题

  1. 数据集中最小的IC50值是多少?

    您的答案:0 nM

  2. 您如何解释IC50值?

    您的答案:IC50值应该始终大于零。零值可能只是在手动记录时未被注意到的错误。此外,零IC50值也可能意味着该化合物对目标无活性,显示有限的抑制效果。

  3. 您现在认为知道最强效的COX2抑制剂是什么吗?

    您的答案:不。尽管我们可以简单地丢弃所有IC50值为零的条目,但在确定最强效的抑制剂之前仍然存在一些其他问题。理想情况下,当将所有文献中报道的实验IC50数据输入数据库时,应将其转换为"标准值",其"标准单位"为纳摩尔(nM)。但是,如果在记录值时单位被正确转换,而值没有经过转换(例如,0.005 uM -> 0.005 nM,应该是5 nM),那么数据库中也会出现小于1的值。这些非零的错误值甚至更难以被识别和处理,而且它们与零值一起,当输入到机器学习模型时可能会导致非常偏见的和误导性的预测。

代码
文本

所以,不幸的是,即使有了像ChEMBL数据库和pandas这样强大的工具,由于数据中的错误,要回答什么是最强效的抑制剂这个问题可能并不简单。如果您有兴趣进一步研究这个问题,您需要手动检查这里的顶部注释的论文或依赖于另一个数据来源。但对于这个教程,我们将继续探讨其他问题。

代码
文本

2.3 高级清理

代码
文本

正如你可能已经意识到的,一个没有经过数据策划和清洗步骤的"原始"数据集对我们来说远远没有用处,因为存在各种问题。除了不准确和不相关的数据,其他的不一致性,如缺失数据或重复数据,也应该被正确地识别和处理。

代码
文本
[31]
# delete entries with misleading and missing values
activity.dropna(subset = ['standard_value', 'canonical_smiles', 'pchembl_value'], inplace = True) # delete missing data
activity.drop(activity[activity["standard_value"] == 0].index, inplace = True) # delete wrong annotations
代码
文本

为了分析的便利,我们将整个数据集根据生物活性类型分为三个单独的数据集。

代码
文本
[32]
# split the whole dataset into three individual datasets according to bioactivity type
ic50_data = activity.loc[activity['standard_type'] == 'IC50'].copy()

# please follow the above example to create the other two datasets
ki_data = activity.loc[activity['standard_type'] == 'Ki'].copy()
inhibition_data = activity.loc[activity['standard_type'] == 'Inhibition'].copy()
代码
文本

重复条目中的不一致生物活性值可能来自不同的研究或重复输入,这在使用数据集训练机器学习模型时可能会引起严重问题。在我们处理重复数据之前,让我们看一下阿司匹林的测定条目的差异,它是最著名的COX-2抑制剂。

代码
文本
[33]
# 获取所有阿司匹林的IC50条目 (阿司匹林的ChEBML id是: 'CHEMBL25')
aspirin = ic50_data.loc[ic50_data['molecule_chembl_id'] == 'CHEMBL25']
# 对阿司匹林的IC50条目进行简单的统计分析,计算均值、众数和标准偏差(std),然后生成一个条形图来可视化IC50值
mean = statistics.mean(aspirin["standard_value"])
sd = statistics.stdev(aspirin["standard_value"])
mode_ = statistics.mode(aspirin["standard_value"])
range_ = aspirin["standard_value"].max() - aspirin["standard_value"].min()

print("均值: {:0.2f} (nM)" .format(mean))
print('众数: {} (nM)'.format(mode_))
print("标准偏差: {:0.2f} (nM)" .format(sd))
print('相对标准偏差: {:0.2f} %' .format(sd/mean*100))
print("范围: {:0.2f} (nM)" .format(range_))

plt.bar(list(range(len(aspirin.index))), aspirin["standard_value"])
plt.xlabel('assay index')
plt.ylabel('IC50 (nM)')
plt.show()

代码
文本
[34]
# check all aspirin Ki entries
ki_data.loc[ki_data['molecule_chembl_id'] == "CHEMBL25"]
activity_id assay_chembl_id assay_description assay_type canonical_smiles molecule_chembl_id standard_type standard_units standard_value pchembl_value target_chembl_id target_organism
9169 13830396 CHEMBL3088737 Inhibition of COX-2 (unknown origin) using ara... B CC(=O)Oc1ccccc1C(=O)O CHEMBL25 Ki nM 52000.0 4.28 CHEMBL230 Homo sapiens
代码
文本

讨论

根据Cheng-Prusoff方程 ,Ki值永远不应超过IC50值。但是对于阿司匹林,几乎所有的IC50条目都比Ki值小。

所有独立的数据条目都似乎达成了共识,这在数据中是非常不可能的错误。Cheng-Prusoff方程错误吗?它当然是一个正确且科学的数学模型,但关键的前提是抑制剂必须以可逆的方式与目标蛋白竞争性地结合。研究表明,阿司匹林是一个不可逆的抑制剂,与其目标COX-2形成共价键。因此,该方程不能再准确描述阿司匹林的IC50和Ki值之间的数学关系。

代码
文本

好的,现在是时候去除所有重复项了。

代码
文本
[35]
# 如果 IC50 数据集中存在重复项,只保留第一个条目
print('IC50 数据集中有 {} 个重复项。'.format(sum(ic50_data.duplicated('molecule_chembl_id'))))
ic50_data.drop_duplicates(subset='molecule_chembl_id', keep = 'first', inplace = True)
ic50_data.reset_index(drop = True, inplace = True)
print('清洗后,IC50 数据集中还剩下 {} 个重复项。'.format(sum(ic50_data.duplicated('molecule_chembl_id'))))

# 如果 Ki 数据集中存在重复项,只保留第一个条目
print('----------')
print('Ki 数据集中有 {} 个重复项。'.format(sum(ki_data.duplicated('molecule_chembl_id'))))
ki_data.drop_duplicates(subset='molecule_chembl_id', keep = 'first', inplace = True)
ki_data.reset_index(drop = True, inplace = True)
print('清洗后,Ki 数据集中还剩下 {} 个重复项。'.format(sum(ki_data.duplicated('molecule_chembl_id'))))

IC50 数据集中有 1424 个重复项。
清洗后,IC50 数据集中还剩下 0 个重复项。
----------
Ki 数据集中有 0 个重复项。
清洗后,Ki 数据集中还剩下 0 个重复项。
代码
文本

2.4 可视化 IC50 值

代码
文本

现在我们有了一个更加整洁的 IC50 数据集,让我们通过绘制直方图来查看 IC50 值的分布。

代码
文本
[36]
# please write your code below

plt.hist(ic50_data['standard_value'])
plt.xlabel('IC50 value (nM)')
plt.ylabel('frequency')
plt.show()
代码
文本

嗯,您可能会发现这个图不是很有用,因为值似乎分布得很稀疏,并且它们之间可能存在数个数量级的差异。解决此问题的一种方法是绘制对数(以10为底)值。

代码
文本
[37]
# please write your code below

plt.hist(np.log10(ic50_data['standard_value']))
plt.xlabel('log10(IC50 value, nM)')
plt.ylabel('frequency')
plt.show()
代码
文本

我们快完成了!让我们使用10uM(1uM = 1000nM)作为阈值,将所有条目分为“活性”和“非活性”COX-2抑制剂,并将这个结果作为一个新列名为“class_label”添加到IC50 dataframe中。

代码
文本
[38]
# please write your code below

ic50_data['class_label'] = 'inactive'
ic50_data.loc[(ic50_data['standard_value'] <= 10000), ['class_label']] = 'active'
print(ic50_data['class_label'].value_counts(sort=True))
ic50_data.head()
active      2849
inactive     557
Name: class_label, dtype: int64
activity_id assay_chembl_id assay_description assay_type canonical_smiles molecule_chembl_id standard_type standard_units standard_value pchembl_value target_chembl_id target_organism class_label
0 34205 CHEMBL762912 In vitro inhibitory activity against human pro... B Cc1ccc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccccc1 CHEMBL297008 IC50 nM 60.00 7.22 CHEMBL230 Homo sapiens active
1 34209 CHEMBL762912 In vitro inhibitory activity against human pro... B Cc1c(C=O)cc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccc(F)cc1 CHEMBL289813 IC50 nM 3230.00 5.49 CHEMBL230 Homo sapiens active
2 35476 CHEMBL762912 In vitro inhibitory activity against human pro... B Cc1c(COc2cccc(Cl)c2)cc(-c2ccc(S(C)(=O)=O)cc2)n... CHEMBL43736 IC50 nM 80.00 7.10 CHEMBL230 Homo sapiens active
3 36218 CHEMBL769655 Tested in vitro for inhibition against Prostag... B Fc1ccc(-c2[nH]c(-c3ccc(F)cc3)c3c2C2CCC3CC2)cc1 CHEMBL140167 IC50 nM 0.12 9.92 CHEMBL230 Homo sapiens active
4 39073 CHEMBL762912 In vitro inhibitory activity against human pro... B CC(=O)c1cc(-c2ccc(S(C)(=O)=O)cc2)n(-c2ccc(F)cc... CHEMBL44290 IC50 nM 1610.00 5.79 CHEMBL230 Homo sapiens active
代码
文本

2.5 IC50 vs. Ki 相关系数

代码
文本

根据我们的讨论,让我们找出那些同时具有IC50和Ki值的分子,并生成一个散点图来可视化IC50和Ki的关系。

注意:你可以在你的图中包括一个"helper curve y = x",这样所有的点都会分布到分界线的两边。

代码
文本
[39]
# please write your code below

# create a new dataframe merging available IC50 and Ki values
ic50_pre = ic50_data[['activity_id', 'molecule_chembl_id', 'standard_value']].copy()
ic50_pre.rename(columns = {"standard_value": "IC50"}, inplace = True)

ki_pre = ki_data[['activity_id', 'molecule_chembl_id', 'standard_value']].copy()
ki_pre.rename(columns = {"standard_value": "Ki"}, inplace = True)

merged = pd.merge(
ic50_pre[['molecule_chembl_id', 'IC50']],
ki_pre[['molecule_chembl_id', 'Ki']],
on="molecule_chembl_id",
)
merged.head()
molecule_chembl_id IC50 Ki
0 CHEMBL6 49.0 1500.0
1 CHEMBL25 62500.0 52000.0
2 CHEMBL404108 7.0 320.0
3 CHEMBL259218 47.0 1200.0
4 CHEMBL559089 42500.0 65500.0
代码
文本
[40]
# 统计遵循Cheng-Prusoff方程的分子数量
apply = 0
for i in range(len(merged)):
if merged.iloc[i]['IC50'] >= merged.iloc[i]['Ki']:
apply += 1
print('有{}个分子遵循Cheng-Prusoff方程,其中IC50值不小于Ki值。'.format(apply))

有7个分子遵循Cheng-Prusoff方程,其中IC50值不小于Ki值。
代码
文本
[41]
# figures
plt.scatter(np.log10(merged['IC50']), np.log10(merged['Ki'])) # you won't lose scores if you don't plot log values, this is just for clear visualization
plt.plot(np.arange(1, 6, 1), np.arange(1, 6, 1), label = 'y = x', color = 'r')
plt.xlabel("log10(IC50)")
plt.ylabel("log10(Ki)")
plt.legend()
plt.show()
代码
文本

2.6 清洗化学结构

代码
文本

清洗结构是作为一个重要的预处理步骤。其中的一个步骤是去除如盐类的次要组分。通常,在一个SMILES表达式中,两个或多个组分被写为分开的SMILES表达式,并使用"."作为分隔符。因此,检测次要组分可以通过查找"."来执行,并且移除次要组分可以通过仅保留最大的SMILES表达式来完成。

例如:CN(C)C.Cl -> CN(C)C

代码
文本
[43]
# 在IC50数据集中,检查包含多个组件的canonical smiles的数量

salt_count = 0
example = []

smiles = ic50_data['canonical_smiles']
for i in range(len(smiles)):
if "." in smiles[i]:
example.append(smiles[i])
salt_count += 1

print('这里有一个例子:{}'.format(example[0]))
print("有{}个分子在它们的smiles中包含盐组分。".format(salt_count))

这里有一个例子:CS(=O)(=O)c1ccc(-c2cc(N)sc2-c2ccc(F)cc2)cc1.Cl
有32个分子在它们的smiles中包含盐组分。
代码
文本
[46]
# wash structures by removing the salts and other minor components, and update the clean canonical smiles in your dataset

clean_smiles = []

for i in range(len(smiles)):
clean = max(smiles[i].split("."), key = len) # split the smiles by ".", and keep the longest substring
clean_smiles.append(clean)
ic50_data['canonical_smiles'] = clean_smiles
代码
文本
[47]
# 检查结果

updated_smiles = ic50_data["canonical_smiles"]
updated_count = 0

for i in range(len(updated_smiles)):
if "." in updated_smiles[i]:
updated_count += 1
print("清洁后,仍有{}个分子在其smiles中含有盐。".format(updated_count))

清洁后,仍有0个分子在其smiles中含有盐。
代码
文本

3. 输出数据集

代码
文本

好工作!最后一步:将处理过的 IC50 数据集导出为 .csv 文件。

与导入文件类似,pandas 中也有函数可以用来将你的结果导出到文件中。

代码
文本
[ ]
# export your dataframe into a csv file

ic50_data.to_csv('COX-2_IC50.csv')
代码
文本
机器学习
数据集
数据处理
中文
机器学习数据集数据处理中文
已赞3
本文被以下合集收录
QSAR
小炒砂糖桔
更新于 2024-03-29
4 篇2 人关注
learing
微信用户s0uE
更新于 2024-05-15
7 篇0 人关注
推荐阅读
公开
药物管线五维分析框架
药物数据分析
药物数据分析
yufeng
发布于 2023-08-23
5 赞
公开
新手向第二期-药物研发中的药物分子相似度比较
notebook化学信息学生物信息学RDKit药物
notebook化学信息学生物信息学RDKit药物
huangx@dp.tech
发布于 2023-11-13
评论
 虽然我们已经有了一个包含多个记录的数据集...

yufeng

09-25 10:11
我看到有一些其他过滤条件,你看看合理吗: WHERE m.molecule_type = 'Small molecule' AND t.target_type = 'SINGLE PROTEIN' AND a.assay_type = 'B' AND act.standard_relation IN ('=', '<', '~', '<=', '<<') AND act.standard_type IN ('IC50', 'EC50', 'Ki', 'Kd') AND act.standard_units IN ('nM', 'ug.mL-1') AND act.standard_value != 'NULL' AND act.standard_value <> '' AND act.standard_value IS NOT NULL AND t.organism != 'NULL' AND t.organism <> '' AND t.organism IS NOT NULL
展开
评论