MongoDB en 10 mins: Écriture avec python, Lecture avec pandas

Si vous travaillez avec des données, vous avez certainement besoin d'une base de données! Créez votre premier serveur mongodb, écrivez vos données depuis un script python, et analysez les avec pandas dans un notebook jupyter.

This image has an empty alt attribute; its file name is mongodb.png
Lecture depuis une base mongdb, et affichage des données avec pandas

Introduction

Si vous travaillez avec des données, il est plus que probable que vous ayez besoin d'une base de données. Dans cet article vous allez apprendre à :

  • mettre en place un serveur mongodb localement
  • créer une base de données, et la remplir depuis un script python
  • lire les données dans un notebook jupyter pour une analyse avec pandas.

Vous pourriez objecter que vous n'avez en fait pas besoin d'une base de données, car vous stockez vos données dans des fichiers, ou que vous traitez ces données en ligne à la volée.

Ok. Mais au bout d'un certain point, vous vous perdrez peut-être dans tout vos fichiers, et vous ne pourrez plus vous souvenir des conditions dans lesquelles ces fichiers ont été créés.

Ou encore, si vous traitez les données en ligne, que se passera-t'il si votre code d'analyse plante pour une raison ou une autre? Vous voudrez certainement pouvoir traiter les données manquantes après coup. Et si vous ou votre client voulez voir ce qui s'est produit durant une certaine période par le passé?

Certains pourraient aussi hésiter car mettre en place et maintenir un serveur est compliqué, et car cela les forcerait à apprendre SQL...

Image result for le cri munch
SQL

Mais aujourd'hui, des serveurs peuvent être déployés en quelques secondes, et les bases de données NoSQL comme mongodb ont le vent en poupe : elles sont puissantes et faciles à utiliser.

Alors compte à rebours sur 10 minutes, et c'est parti!

Pourquoi mongodb?

Vous vous imaginez peut-être une base de données comme un tableau excel. L'ensemble des colonnes décrit le schéma de la base, et les lignes constituent les entrées.

MongoDB est une base de données NoSQL . Pour nous, cela voudra simplement dire que la base de données n'a pas de schéma prédéfini. Si vous avez des données à stocker, il vous suffit de les stocker telles quelles.

Au contraire, avec une base de données SQL, vous devez reformater vos données pour qu'elles satisfassent le schéma. Et avant même de pouvoir écrire quoi que ce soit, vous devrez réfléchir sérieusement au design du schéma.

Les data scientists, pour la plupart, ne sont pas des experts en bases de données. En tous cas, ce n'est pas mon cas ! Mais ça ne m'empêche pas de mettre régulièrement des bases en oeuvre, et de les utiliser. Parfois, c'est juste pour un petit projet personnel et parfois, je décide ensuite d'agrandir la base de données et d'y stocker une quantité d'information considérable.

MongoDB est facile, rapide, et il est utilisable même pour du big data.

Installation de MongoDB

Pour installer mongodb, il vous suffit de vous référer aux instructions officielles :

J'ai seulement testé les instructions macOS, que je répète ici.

D'abord, installez homebrew si vous ne l'avez pas encore fait. Ensuite :

brew tap mongodb/brew
brew install mongodb-community@4.0

Après l'installation, vous pouvez démarrer le serveur et vous assurer qu'il démarre automatiquement avec la machine en tapant :

brew services start mongodb-community@4.0

Création de votre première base de données

Mongodb est distribué avec client par ligne de commandes avec lequel vous pouvez créer des bases de données, les remplir, et les lire. Utilisons-le :

mongo

Sur la ligne de commandes de mongo, choisissez d'utiliser une base de données que nous appelerons "test". Veuillez noter que la base de données ne sera créée que lorsque nous y écrirons un premier document.

> use test
switched to db test

Créez maintenant une collection dans cette base, et écrivez-y votre premier document :

> db.test1.insert({firstname:'oscar', surname:'peterson'})
WriteResult({ "nInserted" : 1 })

Puis un second :

> db.test1.insert({map:{'x':1, y:[0,1,2]}, name:'a_map'})
WriteResult({ "nInserted" : 1 })

Comme vous pouvez le voir, le second document n'a pas grand chose à voir avec le premier. Mais cela ne pose aucun problème : mongo le digère tranquillement, même si ce document contient une structure de données hiérarchique sur le champ 'x'.

Maintenant, récupérons toutes les entrées :

> db.test1.find()
{ "_id" : ObjectId("5ce54ef809fcaa334f64fad9"), "firstname" : "oscar", "surname" : "peterson" }
{ "_id" : ObjectId("5ce54efd09fcaa334f64fada"), "map" : { "x" : 1, "y" : [ 0, 1, 2 ] }, "name" : "a_map" }

Bien sûr, lorsque vous recherchez des documents dans la base, seuls ceux qui sont pertinents sont retournés :

> db.test1.find({firstname:'oscar'})
{ "_id" : ObjectId("5ce54ef809fcaa334f64fad9"), "firstname" : "oscar", "surname" : "peterson" }

Parfait, mais ceci est quand même un blog sur python, et nous n'allons certainement pas utiliser le client mongo pour remplir notre base de données.

Installation du client mongodb pour python

Nous allons utiliser pymongo pour interagir avec noter base depuis python. Comme d'habitude, nous allons installer nos outils avec Anaconda , car c'est plus simple.

Ouvrez un terminal, et créez un nouvel environnement anaconda, avec tout les packages dont nous aurons besoin :

conda create -n mongo python=3.6 pymongo pandas matplotlib jupyter

pandas, matplotlib et jupyter sont seulement nécessaires à l'analyse des données que nous ferons par la suite. Si vous voulez seulement parler à la base de données, vous pouvez faire l'impasse sur leur installation.

Ensuite, activez cette environnement comme indiqué :

conda activate mongo

Et enfin, assurez-vous que pymongo peut être utilisé :

python -c 'import pymongo; print(pymongo.__version__)'
3.7.2

Écrire dans mongodb depuis python

Voici un petit script que je vous ai préparé. Le script se connecte à la base de données, crée une nouvelle collection, et y stocke 100 points pris sur une sinusoïdale.

mongo_write.py:

import pymongo 
import math

# define the client, the database, and the collection
# the database and the collection are created at first insert 
# if needed
client = pymongo.MongoClient('localhost',27017)
mydb = client["test"]
sinfun = mydb["sin"]

print('insert')
data = []
for i in range(100):
    x = i/10.
    y = math.sin(x)
    data.append({'x':x,'y':y})
# the list of records is written to the database in one go:
sinfun.insert_many(data)
print('done')

Exécutez ce script :

python mongo_write.py

puis vérifiez avec le client mongo que la collection existe que les données ont été écrites correctement :

mongo
> use test
> db.sin.find().limit(5)
{ "_id" : ObjectId("5ce5512f4b8cf21178dd3ecc"), "x" : 0, "y" : 0 }
{ "_id" : ObjectId("5ce5512f4b8cf21178dd3ecd"), "x" : 0.1, "y" : 0.09983341664682815 }
{ "_id" : ObjectId("5ce5512f4b8cf21178dd3ece"), "x" : 0.2, "y" : 0.19866933079506122 }
{ "_id" : ObjectId("5ce5512f4b8cf21178dd3ecf"), "x" : 0.3, "y" : 0.29552020666133955 }
{ "_id" : ObjectId("5ce5512f4b8cf21178dd3ed0"), "x" : 0.4, "y" : 0.3894183423086505 }

Analyse de données depuis mongodb avec pandas

Nous allons maintenant accéder à notre base et analyser les données qui y sont stockées depuis un notebook jupyter. D'abord, démarrez le serveur jupyter:

jupyter notebook

Créez un nouveau notebook python 3, et suivez les instructions ci-dessous.

Connectez-vous au serveur mongodb sur la machine locale, et récupérez la collection sinfun de la base de données test .

In [1]:
import pymongo
client = pymongo.MongoClient('localhost')
sinfun = client.test.sin
sinfun.find_one()
Out[1]:
{'_id': ObjectId('5ce5512f4b8cf21178dd3ecc'), 'x': 0.0, 'y': 0.0}

Demandez tous les documents à la base de données. l'objet cursor est un itérateur, et nous créons une liste à partir de cet itérateur. Veuillez noter qu'après la création de la liste, l'itérateur est épuisé. Si vous souhaitez le réutiliser, il vous faudra exécuter un nouveau find .

In [2]:
import pandas as pd
cursor = sinfun.find()
entries = list(cursor)
entries[:5]
Out[2]:
[{'_id': ObjectId('5ce5512f4b8cf21178dd3ecc'), 'x': 0.0, 'y': 0.0},
 {'_id': ObjectId('5ce5512f4b8cf21178dd3ecd'),
  'x': 0.1,
  'y': 0.09983341664682815},
 {'_id': ObjectId('5ce5512f4b8cf21178dd3ece'),
  'x': 0.2,
  'y': 0.19866933079506122},
 {'_id': ObjectId('5ce5512f4b8cf21178dd3ecf'),
  'x': 0.3,
  'y': 0.29552020666133955},
 {'_id': ObjectId('5ce5512f4b8cf21178dd3ed0'),
  'x': 0.4,
  'y': 0.3894183423086505}]

Enfin, créons une dataframe pandas à partir de la liste d'entrées pour pouvoir tracer les données facilement.

In [3]:
df = pd.DataFrame(entries)
df.head()
Out[3]:
_id x y
0 5ce5512f4b8cf21178dd3ecc 0.0 0.000000
1 5ce5512f4b8cf21178dd3ecd 0.1 0.099833
2 5ce5512f4b8cf21178dd3ece 0.2 0.198669
3 5ce5512f4b8cf21178dd3ecf 0.3 0.295520
4 5ce5512f4b8cf21178dd3ed0 0.4 0.389418
In [5]:
df.plot('x')
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x121449470>

Conclusion

Dans cet article, vous avez appris que vous pouvez mettre en place un serveur de base de données très rapidement, et que mongodb est un jeu d'enfant!

Vous avez aussi vu comment vous connecter à cette base depuis un script python, et comment afficher les données avec pandas depuis un notebook jupyter.

J'ai voulu rester très simple pour ce petit exemple, et je suis sûr qu'il vous sera néanmoins utile. Par la suite, nous verrons comment accéder au serveur mongodb depuis une machine distante, et comment remplir et lire de manière asynchrone, pour un affichage interactif basé sur bokeh.


N'hésitez pas à me donner votre avis dans les commentaires ! Je répondrai à toutes les questions.

Et si vous avez aimé cet article, vous pouvez souscrire à ma newsletter pour être prévenu lorsque j'en sortirai un nouveau. Pas plus d'un mail par semaine, promis!

Retour


Encore plus de data science et de machine learning !

Rejoignez ma mailing list pour plus de posts et du contenu exclusif:

Je ne partagerai jamais vos infos.
Partagez si vous aimez cet article: