【化学でPython】pandas:大量の実験データをサクッと整理・解析する
はじめに
この「化学でPython」シリーズでは、化学の分野で有用な Python ライブラリを紹介しています。
今回紹介するのは、pandas です。
pandas とは?
実験データの整理整頓や表計算を強力にサポートする、Python版のExcelとも言えるライブラリです。
化学に限らず、データ分析を行う全人類にとって必須のツール。数万行ある化合物データや実験結果のCSVも、pandasなら一瞬で読み込み、加工、集計ができます。
インストール
pip で簡単にインストールできます。Excelファイルを扱うために openpyxl も一緒に入れておくと便利です。
pip install pandas openpyxl
基本的な使い方
まずは、最も基本的な使い方として、データの作成と確認を行ってみましょう。
pandasでは DataFrame(データフレーム) という表形式のオブジェクトを操作します。
import pandas as pd
# 辞書からDataFrameを作成(実験ノートのイメージ)
data = {
'Compound_ID': ['C001', 'C002', 'C003'],
'SMILES': ['CCO', 'CC(=O)O', 'c1ccccc1'],
'MW': [46.07, 60.05, 78.11],
'Yield': [85.5, 92.0, 78.3]
}
df = pd.DataFrame(data)
# データの表示
print("--- データフレーム ---")
print(df)
# 基本統計量の確認(平均や最大・最小など)
print("\n--- 基本統計量 ---")
print(df.describe())
--- データフレーム ---
Compound_ID SMILES MW Yield
0 C001 CCO 46.07 85.5
1 C002 CC(=O)O 60.05 92.0
2 C003 c1ccccc1 78.11 78.3
--- 基本統計量 ---
MW Yield
count 3.000000 3.000000
mean 61.410000 85.266667
std 16.063238 6.852980
min 46.070000 78.300000
25% 53.060000 81.900000
50% 60.050000 85.500000
75% 69.080000 88.750000
max 78.110000 92.000000
実践例: 化合物ライブラリのスクリーニングと集計
実践的な例として、「化合物データセットから条件に合うものを抽出し、骨格ごとの傾向を分析する」 タスクをやってみます。
創薬化学や材料探索でよくある、「分子量やLogPでフィルタリングして、有望な骨格を見つける」というシナリオです。
1. データの準備とフィルタリング
まず、仮想的な化合物データセットを作成し、Lipinskiの法則(の一部)のような基準でフィルタリングします。
ここでは、「分子量 (MW) が 500以下」かつ「LogP が 5以下」の化合物を抽出します。
import pandas as pd
# 仮想的な化合物データセット
data = {
'ID': ['Mol_1', 'Mol_2', 'Mol_3', 'Mol_4', 'Mol_5', 'Mol_6'],
'Scaffold': ['Benzene', 'Pyridine', 'Benzene', 'Indole', 'Pyridine', 'Indole'],
'MW': [150.2, 420.5, 550.1, 230.3, 180.2, 510.4],
'LogP': [1.2, 4.5, 5.8, 2.1, 1.5, 5.2],
'Activity_IC50': [50, 12, 1000, 8, 45, 900] # nM
}
df = pd.DataFrame(data)
print(f"元のデータ数: {len(df)}")
# 条件によるフィルタリング
# MW <= 500 かつ LogP <= 5
filtered_df = df[ (df['MW'] <= 500) & (df['LogP'] <= 5) ].copy()
print(f"フィルタリング後のデータ数: {len(filtered_df)}")
print("\n--- 抽出された化合物 ---")
print(filtered_df[['ID', 'MW', 'LogP']])
元のデータ数: 6
フィルタリング後のデータ数: 4
--- 抽出された化合物 ---
ID MW LogP
0 Mol_1 150.2 1.2
1 Mol_2 420.5 4.5
3 Mol_4 230.3 2.1
4 Mol_5 180.2 1.5
2. 骨格ごとの集計と新しい指標の計算
次に、抽出した化合物について、新しい指標(ここでは簡易的なリガンド効率として -log(IC50) / MW のようなもの)を計算し、骨格 (Scaffold) ごとに平均値を算出します。
import numpy as np
# 新しい列を追加: pIC50 (簡易計算: -log10(IC50 * 10^-9))
# IC50はnM単位なので * 1e-9 しています
filtered_df['pIC50'] = -np.log10(filtered_df['Activity_IC50'] * 1e-9)
# 骨格ごとの平均値を算出
scaffold_summary = filtered_df.groupby('Scaffold')[['MW', 'pIC50']].mean()
print("--- 骨格ごとの平均値 ---")
print(scaffold_summary)
# 結果をCSVに保存
filtered_df.to_csv('filtered_compounds.csv', index=False)
--- 骨格ごとの平均値 ---
MW pIC50
Scaffold
Benzene 150.20 7.301030
Indole 230.30 8.096910
Pyridine 300.35 7.633803
結果を見ると、このデータセットでは Indole 骨格を持つ化合物が、平均的に高いpIC50(活性)を示していることがわかります(データ数が少ないのであくまで例ですが)。
このように groupby を使うと、構造活性相関 (SAR) の傾向を簡単に掴むことができます。
まとめ
今回は pandas を紹介しました。
- Point 1: 化学データの読み込み・整理・保存が数行で完結します。
- Point 2: 条件によるフィルタリングで、膨大なライブラリから有望な化合物を一瞬で絞り込めます。
-
Point 3:
groupbyなどの集計機能を使えば、骨格ごとの傾向分析も簡単です。
ぜひ試してみてください。
Discussion