Résumé des mesures#
À partir d’une base de données accessible par SQL contenant des informations sur les expériences, les images acquises pendant les expériences et les mesures correspondantes, nous aimerions extraire des statistiques récapitulatives.
import pandas as pd
from pandasql import sqldf
experiment = pd.read_csv("../../data/experiments.csv")
image = pd.read_csv("../../data/images.csv")
overview = pd.read_csv("../../data/overview.csv")
query_database = lambda q: sqldf(q, globals())
Données d’exemple#
Juste un rappel, notre tableau d’aperçu contient les informations clés extraites de notre base de données sur le nombre de cellules comptées dans les images qui ont été acquises pendant les expériences.
query = """
SELECT *
FROM overview
"""
query_database(query)
| Unnamed: 0 | experiment_name | Filename | time_after_exposure_in_s | number_of_cells | |
|---|---|---|---|---|---|
| 0 | 0 | High dose | image0.tif | 0 | 96 |
| 1 | 1 | High dose | image0.tif | 1 | 47 |
| 2 | 2 | High dose | image0.tif | 2 | 32 |
| 3 | 3 | High dose | image0.tif | 3 | 24 |
| 4 | 4 | High dose | image0.tif | 4 | 19 |
| ... | ... | ... | ... | ... | ... |
| 95 | 95 | Control | image9.tif | 5 | 142 |
| 96 | 96 | Control | image9.tif | 6 | 148 |
| 97 | 97 | Control | image9.tif | 7 | 144 |
| 98 | 98 | Control | image9.tif | 8 | 141 |
| 99 | 99 | Control | image9.tif | 9 | 140 |
100 rows × 5 columns
Regroupement des lignes#
L’instruction GROUP BY permet de regrouper de longs tableaux en tableaux plus courts et nous permet de faire des statistiques descriptives. Nous pouvons par exemple déterminer le plus petit et le plus grand nombre de cellules observées au cours d’une expérience en utilisant les agrégateurs appelés MIN() et MAX().
query = """
SELECT experiment_name, MIN(number_of_cells), MAX(number_of_cells)
FROM overview
GROUP BY experiment_name
"""
query_database(query)
| experiment_name | MIN(number_of_cells) | MAX(number_of_cells) | |
|---|---|---|---|
| 0 | Control | 113 | 159 |
| 1 | High dose | 9 | 151 |
| 2 | Medium dose | 7 | 158 |
Des groupes peuvent également être formés en utilisant plusieurs colonnes. Ici, nous voyons aussi qu’il est courant de spécifier les colonnes utilisées pour le regroupement deux fois, une fois après GROUP BY et une fois après SELECT car nous voulons voir le regroupement dans le tableau.
query = """
SELECT experiment_name, Filename, MIN(number_of_cells), MAX(number_of_cells)
FROM overview
GROUP BY experiment_name, Filename
"""
query_database(query)
| experiment_name | Filename | MIN(number_of_cells) | MAX(number_of_cells) | |
|---|---|---|---|---|
| 0 | Control | image6.tif | 147 | 156 |
| 1 | Control | image7.tif | 113 | 122 |
| 2 | Control | image8.tif | 145 | 159 |
| 3 | Control | image9.tif | 140 | 149 |
| 4 | High dose | image0.tif | 9 | 96 |
| 5 | High dose | image1.tif | 15 | 151 |
| 6 | High dose | image2.tif | 9 | 97 |
| 7 | Medium dose | image3.tif | 15 | 158 |
| 8 | Medium dose | image4.tif | 7 | 76 |
| 9 | Medium dose | image5.tif | 14 | 147 |
Une stratégie similaire utilise l’agrégateur COUNT pour compter le nombre d’images acquises par expérience.
query = """
SELECT experiment_name, COUNT(Filename)
FROM overview
GROUP BY experiment_name
"""
query_database(query)
| experiment_name | COUNT(Filename) | |
|---|---|---|
| 0 | Control | 40 |
| 1 | High dose | 30 |
| 2 | Medium dose | 30 |
Combinaison de statistiques#
Supposons que les mesures dans notre base de données résultent d’une analyse en time-lapse. Un coup d’œil rapide à un seul fichier d’image et aux mesures correspondantes montre que le nombre de cellules diminue au fil du temps.
query = """
SELECT *
FROM overview
WHERE Filename = "image0.tif"
"""
query_database(query)
| Unnamed: 0 | experiment_name | Filename | time_after_exposure_in_s | number_of_cells | |
|---|---|---|---|---|---|
| 0 | 0 | High dose | image0.tif | 0 | 96 |
| 1 | 1 | High dose | image0.tif | 1 | 47 |
| 2 | 2 | High dose | image0.tif | 2 | 32 |
| 3 | 3 | High dose | image0.tif | 3 | 24 |
| 4 | 4 | High dose | image0.tif | 4 | 19 |
| 5 | 5 | High dose | image0.tif | 5 | 16 |
| 6 | 6 | High dose | image0.tif | 6 | 13 |
| 7 | 7 | High dose | image0.tif | 7 | 11 |
| 8 | 8 | High dose | image0.tif | 8 | 10 |
| 9 | 9 | High dose | image0.tif | 9 | 9 |
Nous pouvons maintenant déterminer le nombre moyen de cellules au début de l’expérience en faisant la moyenne des 3 premiers points temporels.
query = """
SELECT Filename, AVG(number_of_cells) as number_of_cells
FROM overview
WHERE time_after_exposure_in_s < 3
GROUP BY Filename
"""
query_database(query)
| Filename | number_of_cells | |
|---|---|---|
| 0 | image0.tif | 58.333333 |
| 1 | image1.tif | 93.000000 |
| 2 | image2.tif | 58.000000 |
| 3 | image3.tif | 97.333333 |
| 4 | image4.tif | 46.333333 |
| 5 | image5.tif | 89.666667 |
| 6 | image6.tif | 150.666667 |
| 7 | image7.tif | 113.666667 |
| 8 | image8.tif | 151.000000 |
| 9 | image9.tif | 147.666667 |
query = """
SELECT Filename, AVG(number_of_cells) as number_of_cells
FROM overview
WHERE time_after_exposure_in_s < 3
GROUP BY Filename
"""
cell_count_early = query_database(query)
query = """
SELECT Filename, AVG(number_of_cells) as number_of_cells
FROM overview
WHERE time_after_exposure_in_s > 6
GROUP BY Filename;
"""
cell_count_late = query_database(query)
query = """
SELECT cell_count_early.Filename, (cell_count_late.number_of_cells / cell_count_early.number_of_cells) AS cell_count_ratio
FROM cell_count_early
INNER JOIN cell_count_late ON cell_count_early.Filename = cell_count_late.Filename
"""
cell_count_ratio_overview = query_database(query)
cell_count_ratio_overview
| Filename | cell_count_ratio | |
|---|---|---|
| 0 | image0.tif | 0.171429 |
| 1 | image1.tif | 0.182796 |
| 2 | image2.tif | 0.172414 |
| 3 | image3.tif | 0.171233 |
| 4 | image4.tif | 0.172662 |
| 5 | image5.tif | 0.174721 |
| 6 | image6.tif | 0.986726 |
| 7 | image7.tif | 1.055718 |
| 8 | image8.tif | 0.991170 |
| 9 | image9.tif | 0.959368 |
Nous connaissons maintenant la fraction de cellules qui ont survécu dans chaque fichier. Nous devons utiliser à nouveau l’instruction JOIN pour savoir dans quelle expérience ces taux de survie ont été observés.
query = """
SELECT experiment.Comment, cell_count_ratio_overview.cell_count_ratio
FROM cell_count_ratio_overview
INNER JOIN image ON cell_count_ratio_overview.Filename = image.Filename
INNER JOIN experiment ON image.experiment_ID = experiment.ID
"""
query_database(query)
| Comment | cell_count_ratio | |
|---|---|---|
| 0 | High dose | 0.171429 |
| 1 | High dose | 0.182796 |
| 2 | High dose | 0.172414 |
| 3 | Medium dose | 0.171233 |
| 4 | Medium dose | 0.172662 |
| 5 | Medium dose | 0.174721 |
| 6 | Control | 0.986726 |
| 7 | Control | 1.055718 |
| 8 | Control | 0.991170 |
| 9 | Control | 0.959368 |
Celles-ci peuvent également être résumées en utilisant l’instruction GROUP BY. Les bons scientifiques ne rapportent pas seulement la moyenne de ces mesures, mais aussi le nombre d’images qui ont été analysées.
query = """
SELECT
experiment.Comment as experiment_name,
AVG(cell_count_ratio_overview.cell_count_ratio) as mean_cell_count_ratio,
COUNT(cell_count_ratio_overview.cell_count_ratio) as num_images
FROM cell_count_ratio_overview
INNER JOIN image ON cell_count_ratio_overview.Filename = image.Filename
INNER JOIN experiment ON image.experiment_ID = experiment.ID
GROUP BY experiment.Comment
"""
query_database(query)
| experiment_name | mean_cell_count_ratio | num_images | |
|---|---|---|---|
| 0 | Control | 0.998246 | 4 |
| 1 | High dose | 0.175546 | 3 |
| 2 | Medium dose | 0.172872 | 3 |
Exercice#
Déterminez le nombre moyen de cellules sur l’ensemble du time-lapse pour toutes les images individuellement.
Résumez ces mesures pour les images individuelles afin de présenter la moyenne pour chaque expérience.