🧪

【化学でPython】pandas:大量の実験データをサクッと整理・解析する

に公開

はじめに

この「化学でPython」シリーズでは、化学の分野で有用な Python ライブラリを紹介しています。

今回紹介するのは、pandas です。

pandas とは?

実験データの整理整頓や表計算を強力にサポートする、Python版のExcelとも言えるライブラリです。

化学に限らず、データ分析を行う全人類にとって必須のツール。数万行ある化合物データや実験結果のCSVも、pandasなら一瞬で読み込み、加工、集計ができます。

  • 公式サイト: Link
  • GitHub: Link (47.2k ⭐️)

インストール

pip で簡単にインストールできます。Excelファイルを扱うために openpyxl も一緒に入れておくと便利です。

terminal
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