Cet article est la suite de celui que j'ai publié l'autre jour.
Cette fois, j'ai personnellement collecté des données de fluctuation de prix BitCoint avec une certaine API Rest et elles sont devenues trop lourdes, donc j'écrirai quand j'ai sous-échantillonné et réduit le nombre de documents.
C'est un processus d'agrégation. Dans pymongo, le traitement d'agrégation est exécuté en passant un pipeline (instruction conditionnelle) à la fonction d'agrégation. La ligne de base se compose d'une étape et d'un opérateur, et l'étape correspond à "sélectionner", "grouper par", "où", etc. pour SQL, et l'opérateur correspond à "somme", "max", "min", etc. ..
Référence: Aggregate Pipeline (stage) Référence: Aggregate Pileline (opérateur)
Suite à la mise en l'état du résultat de l'acquisition de l'API Rest dans la collection, J'ai mis beaucoup de données comme les suivantes en vain (51240). (Si je l'ai laissé plusieurs jours à 10 minutes d'intervalle, il se serait accumulé avant que je ne le sache ...) Comme c'est ennuyeux, je l'ai sous-échantillonné pour réduire le nombre de données.
Documents stockés dans la collection
client = MongoClient()
db = client["BitCoin"]["document"]
pprint(db.count()) #Fonction pour obtenir le nombre de documents de la collection
pprint(db.find_one())
"""
#Résultat de sortie
51240
{'_id': ObjectId('5f328ad85ae5ac59aee515cb'),
'best_ask': 1245419.0,
'best_ask_size': 0.02,
'best_bid': 1244658.0,
'best_bid_size': 0.05,
'ltp': 1245615.0,
'product_code': 'BTC_JPY',
'tick_id': 10956004,
'timestamp': 1597115465.0,
'total_ask_depth': 1364.44898005,
'total_bid_depth': 1637.4300907,
'volume': 126756.67774321,
'volume_by_product': 6571.45287901
}
"""
Le graphique ressemble à ceci ... Il y a trop de points et c'est vraiment ennuyeux
Pour le moment, nous avons regroupé les données à intervalles de 10 minutes en données quotidiennes, moyenné chaque valeur et sous-échantillonné.
Vous trouverez ci-dessous le pipeline d'agrégats utilisé dans pymongo.
pipeline
coin = "BTC_JPY"
interval = 60*60*24 # 24hour
pipeline = [
# match stage
{"$match": {"product_code": coin} },
# group stage
{"$group": {
"_id":
{"timestamp":
{"$subtract": ["$timestamp", { "$mod": ["$timestamp", interval]}]
}
,
"product_code": "$product_code"
},
"timestamp":{"$avg": "$timestamp"},
"ltp": {"$avg": "$ltp"},
"best_ask": {"$avg": "$best_ask"},
"best_ask_size": {"$avg": "$best_ask_size"},
"best_bid_size": {"$avg": "$best_bid_size"},
"total_ask_depth": {"$avg": "$total_ask_depth"},
"total_bid_depth": {"$avg": "$total_bid_depth"},
"volume": {"$avg": "$volume"},
"volume_by_product": {"$avg": "$volume_by_product"},
}},
# presentation stage
{"$project": {
"product_code": "$_id.product_code",
"_id": 0, "timestamp": 1,"ltp": 1,
"best_ask": 1,"best_ask_size": 1,
"best_bid_size": 1,
"total_ask_depth": 1,
"total_bid_depth": 1,
"volume": 1, "volume_by_product": 1,
}
}
]
Je vais expliquer le pipeline.
Obtenez la cible à agréger («$ match»)
Cette fois, j'ai ceux avec le même product_code
.
(Vous pouvez le spécifier de la même manière que find.)
{"$match": {"product_code": coin} }, ```
Regroupement ($ group
)
Le code_produit et l'horodatage ont été regroupés de manière à correspondre à l'heure unix à des intervalles d'un jour, et les autres valeurs ont été moyennées.
Les deux points suivants peuvent être mentionnés.
Définissez la cible à regrouper dans _id
Après _id
, spécifiez la clé que vous souhaitez obtenir, la valeur maximale, etc. et la méthode de calcul (opérateur).
{"$group": {
"_id": #Définissez ici la cible à regrouper
{"timestamp":
{"$subtract":
["$timestamp",
{ "$mod": ["$timestamp", interval]}]
}
,
"product_code": "$product_code"
},
"timestamp":{"$avg": "$timestamp"},
"ltp": {"$avg": "$ltp"},
Spécifiez les données à afficher ($ project
)
(Vous pouvez le faire avec la même opération que le projet dans find
)
{"$project": {
"product_code": "$_id.product_code",
"_id": 0, "timestamp": 1,"ltp": 1,
"best_ask": 1,"best_ask_size": 1,
"best_bid_size": 1,
"total_ask_depth": 1,
"total_bid_depth": 1,
"volume": 1, "volume_by_product": 1,
}
}
J'ai comparé les données sous-échantillonnées par le pipeline plus tôt avec les données d'origine. Le point rouge est avant le sous-échantillonnage et le bleu après le sous-échantillonnage. Vous pouvez voir que les données sont bien éclaircies.
import matplotlib.pyplot as plt
plt.figure()
for i in db.find( filter= {"product_code": coin
} ):
plt.scatter(i["timestamp"], i["ltp"], marker=".", color="r")
for i in db.aggregate(pipeline=pipeline):
plt.scatter(i["timestamp"], i["ltp"], marker=".", color="b")
plt.grid()
plt.xlabel("Data[unixtime]")
plt.ylabel(coin)
plt.savefig("test2.jpg ")
plt.show()
Eh bien, il y a encore beaucoup de choses sur les agrégats, mais il y en a trop, donc cette fois je vais m'arrêter ici. J'ajouterai des corrections, des questions et tout ce que je veux que vous écriviez.
Recommended Posts