Empfehlung zur Datenanalyse mit MessagePack

MessagePack ist ein von Herrn Furuhashi von Treasure Data vorgeschlagenes und implementiertes Datenserialisierungsformat, das als Format für die Kommunikation zwischen fluentd bekannt ist. Und ich denke du bist. Persönlich verwende ich dies häufig, um Daten bei der Datenanalyse zu speichern, und in diesem Artikel wird die Methode vorgestellt.

Obwohl ich versuche, den Artikel so genau wie möglich zu schreiben, bin ich relativ amateurhaft in Bezug auf Datenanalyse, daher begrüße ich Ihre Vorschläge und Kommentare.

Was tun mit MessagePack?

Sie möchten lediglich die ** Daten, die für die Analyse im MessagePack-Format erhalten wurden, in einer Datei speichern und die Daten zum Zeitpunkt der Analyse lesen **.

Normalerweise scheint es bei der Durchführung von Datenanalysen usw. der königliche Weg zu sein, diese einmal in einer Datenbank usw. zu speichern und dann die Analyse durchzuführen. In den folgenden Fällen denke ich jedoch, dass das Speichern und Lesen im MessagePack-Format von Vorteil ist. ..

Wenn Sie mit MessagePack zufrieden sind

Wenn das Schema unklare Daten verarbeitet

Wenn die von einem bestimmten System ausgegebenen Daten beispielsweise JSON im Wörterbuchformat sind, sind die in jedem Datensatz enthaltenen Schlüssel unterschiedlich, das Format der als Wert eingegebenen Daten ist unterschiedlich und es ist nicht bekannt, ob das Wörterbuchformat oder das Arrayformat vorliegt. Oder sowas ähnliches. Selbst wenn sich der Schlüssel oder Wert ändert, ist es gut, wenn ein solches Schema oder eine solche Spezifikation richtig definiert ist. Es gibt jedoch Fälle, in denen keine andere Wahl bleibt, als aus den tatsächlichen Daten ohne die Spezifikation zu schätzen.

In einem solchen Fall kann MessagePack die hierarchische Struktur wie Wörterbücher und Arrays fast so konvertieren und verwenden, dass es einfach ist, sie in die Datei einzufügen, ohne vorerst über irgendetwas nachzudenken. Beim Abrufen von Daten für die Datenanalyse wird die Daten-E / A häufig zu einem Engpass. Wenn Sie sie also lokal in einem Dateiformat speichern, können Sie später leichter Versuche und Fehler durchführen.

Wenn Sie Daten vorübergehend speichern möchten oder wenn Sie Daten wiederholt speichern und laden möchten

Es gibt viele Dinge, die als Datenanalyse bezeichnet werden können, aber es ist häufig erforderlich, eine "explorative Datenanalyse" durchzuführen, um das gesamte Bild zu erfassen und eine Hypothese zu formulieren, während die Daten in dem Stadium geknetet werden, in dem keine ausreichende Hypothese aufgestellt werden kann. In einem solchen Fall können Sie die Daten in ein einfach zu verarbeitendes Format konvertieren, nur die erforderlichen Daten extrahieren und speichern und so weiter. In diesem Fall kann es zu Problemen mit dem Datenformat kommen, z. B. "Ich möchte dieses Attribut für einen Moment hinzufügen" oder "Es scheint besser, es als Wörterbuch anstelle einer Liste zu speichern".

Bei der Verarbeitung, während das Datenformat auf diese Weise flexibel geändert wird, wenn die Codeseite geändert wird, indem das Schema erneut an einer anderen Stelle als dem Code definiert wird, der die Daten verarbeitet (z. B. Erstellen einer Tabelle mit SQL) usw. In jedem Fall können Inkonsistenzen auftreten, die sehr ärgerlich sein können. Wenn Sie Daten im MessagePack-Format speichern möchten, müssen Sie natürlich das Datenformat sowohl zum Schreiben als auch zum Lesen anpassen, aber der Arbeitsaufwand ist minimal.

(Wenn Sie jedoch bis zu einem gewissen Grad keine Kommentare hinterlassen, verstehen Sie die Bedeutung möglicherweise überhaupt nicht, selbst wenn Sie den Code einige Monate später selbst überprüfen ...)

Wenn Sie Daten mit hoher Geschwindigkeit (aber Volltext) speichern und laden müssen

DB als Middleware speichert nicht nur Daten, sondern bietet auch verschiedene Funktionen wie das Einstellen von Schlüsseln und die Gewährleistung der Zuverlässigkeit. Dies erfordert mehr Aufwand als das einfache Schreiben auf die Festplatte. .. Dies kann durch Techniken wie die Lastverteilung gelöst werden. Wenn Sie jedoch nur "ein wenig Daten speichern" möchten, können Sie diese in das MessagePack-Format konvertieren und direkt als Datei schreiben. Die Leistung beim Schreiben und Lesen von Dateien wird jedoch fast unverändert angewendet.

Die Zuverlässigkeit entspricht jedoch dem Schreiben in eine Datei, und es wird davon ausgegangen, dass beim Lesen alle Daten gelesen werden.

Wenn Sie mit MessagePack nicht zufrieden sind

Andererseits gibt es natürlich Fälle, in denen es nicht geeignet ist, im MessagePack-Format zu speichern und die Daten zu analysieren.

  1. Wenn Sie Daten mit einem eindeutigen Schema oder Daten verwenden, die ursprünglich von der Datenbank usw. organisiert wurden. --Sie sollten die von DB bereitgestellten Funktionen leise nutzen
  2. Für Analysen wie Suche und Aggregation, bei denen die Vorteile der Erstellung von Schlüsseln und Indizes groß sind.
  1. Wenn mehrere Personen dieselben Daten verarbeiten ――Dieses Mal wird davon ausgegangen, dass eine Datei gelesen und geschrieben wird, sodass Sperren usw. nicht berücksichtigt werden
  2. Gewährleistung der Vertraulichkeit, Integrität und Verfügbarkeit von Daten

Alternativer Vorschlag

Die folgenden Technologien können als Alternativen betrachtet werden. Bitte wählen Sie je nach Situation.

CSV

Es ist besser, CSV (oder TSV) zu verwenden, wenn die Daten in einem Spaltenformat mit nahezu fester Länge und nicht hierarchisch strukturiert sind. Es ist jedoch einfacher, MessagePack zu verwenden, wenn Elemente variabler Länge und hierarchische Strukturen enthalten sind.

MongoDB

Sie können in eine dokumentorientierte Datenbank einfügen, ohne ein Schema zu definieren, sodass Sie dies auch vor dem Speichern von Daten tun können. Die Leistung des Einfügens scheint jedoch [3.500 Einfügen / Sek. Zu viel] zu sein (https://www.arangodb.com/2015/10/benchmark-postgresql-mongodb-arangodb/), und beim Schreiben mit MessagePack wird nur direkt auf die Festplatte geschrieben Das Speichern mit MessagePack, das die Leistung der Festplatten-E / A beibehält, ist überwältigend schneller. Wenn Sie jedoch später Schlüssel erstellen möchten, ist MongoDB besser geeignet.

JSON, BSON

Es ist im Vergleich zu MessagePack hinsichtlich Verarbeitungsgeschwindigkeit und Datengröße nachteilig (Referenz). Außerdem ist JSON ein Modul, das in Schritten wie ijson ausgelesen wird, wenn Sie mehrere Objekte in ein Datensegment (z. B. eine Datei) einfügen möchten. Wenn Sie es nicht verwenden, müssen Sie alles auf einmal analysieren. Wenn also die Anzahl der Daten groß ist, ist die Verarbeitung auf einem schlechten Computer schwierig. Wenn Sie es jedoch wie ijson schreiben, wird der Code kompliziert, sodass ich persönlich denke, dass es einfacher ist, Daten kontinuierlich in einem Datensegment zu speichern und gehorsam abzurufen.

Protocol Buffers

Protokollpuffer sind als eine der Serialisierungstechnologien bekannt, aber es braucht Zeit, um Daten zu verarbeiten, deren Schema unklar ist, da das Schema auf der Seite des Verarbeitungscodes definiert werden muss. Als Datenserialisierung als Schnittstelle zwischen Software betrachtet, ist dies praktisch, da es das Schema reguliert. In Fällen, in denen Sie nicht wissen, welche Art von Schemadaten kommen werden, wird es jedoch schwierig, damit umzugehen.

Beispielcode

Auf der offiziellen Seite gibt es viele Erklärungen, daher muss ich nicht viel reden, aber ich werde mich darauf konzentrieren, in die Datei zu schreiben und zu lesen und den Beispielcode einzuführen. Der Code ist auch auf [github] zu finden (https://github.com/m-mizutani/msgpack-file-sample).

In jedem Fall müssen die folgenden Daten in die Datei "data.msg" geschrieben / gelesen werden.

{
  "name": "Alice", 
  "age": 27,
  "hist": [5, 3, 1]
}
{
  "name": "Bob", 
  "age": 33,
  "hist": [4, 5]
}

Python

Paket msgpack-python ist erforderlich.

Installation

$ pip install msgpack-python

Schreiben Sie einen Beispielcode

# coding: UTF-8

import msgpack

obj1 = {
    "name": "Alice",
    "age": 27,
    "hist": [5, 3, 1]
}
obj2 = {
    "name": "Bob",
    "age": 33,
    "hist": [4, 5]
}

with open('data.msg', 'w') as fd:
    fd.write(msgpack.packb(obj1))
    fd.write(msgpack.packb(obj2))

Lesen Sie den Beispielcode

# coding: UTF-8

import msgpack

for msg in msgpack.Unpacker(open('data.msg', 'rb')):
    print msg

Ruby

Paket msgpack ist erforderlich.

$ gem install msgpack

Schreiben Sie einen Beispielcode

# -*- coding: utf-8 -*-

require "msgpack"

obj1 = {
    "name": "Alice",
    "age": 27,
    "hist": [5, 3, 1]
}
obj2 = {
    "name": "Bob",
    "age": 33,
    "hist": [4, 5]
}

File.open("data.msg", "w") do |file|
  file.write(obj1.to_msgpack)
  file.write(obj2.to_msgpack)
end

Lesen Sie den Beispielcode

# -*- coding: utf-8 -*-

require "msgpack"

File.open("data.msg") do |file|
  MessagePack::Unpacker.new(file).each do |obj|
    puts obj
  end
end

Node

Es gibt einige wichtige MessagePack-Bibliotheken, aber dieses Mal werde ich "msgpack-lite" für den Code verwenden.

$ npm install msgpack-lite

Schreiben Sie einen Beispielcode

const fs = require('fs');
const msgpack = require('msgpack-lite');

const obj1 = {
  name: "Alice",
  age: 27,
  hist: [5, 3, 1]
};
const obj2 = {
  name: "Bob",
  age: 33,
  hist: [4, 5]
};

fs.open('data.msg', 'w', (err, fd) => {
  fs.writeSync(fd, msgpack.encode(obj1));
  fs.writeSync(fd, msgpack.encode(obj2));
});

Lesen Sie den Beispielcode

const fs = require('fs');
const msgpack = require('msgpack-lite');

var rs = fs.createReadStream('data.msg');
var ds = msgpack.createDecodeStream();

rs.pipe(ds).on('data', (msg) => {
  console.log(msg);
});

C++

Die msgpackc Bibliothek ist erforderlich. Für MacOS können Sie es mit Brew installieren.

$ brew install msgpack

Schreiben Sie einen Beispielcode

#include <msgpack.hpp>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int fd = open("data.msg", O_WRONLY | O_CREAT, 0600);

  msgpack::sbuffer buf1, buf2;;
  msgpack::packer<msgpack::sbuffer> pk1(&buf1), pk2(&buf2);

  pk1.pack_map(3);
  pk1.pack("name"); pk1.pack("Alice");
  pk1.pack("age");  pk1.pack(27);
  pk1.pack("hist");
  pk1.pack_array(3);
  pk1.pack(5); pk1.pack(3); pk1.pack(1);

  write(fd, buf1.data(), buf1.size());


  pk2.pack_map(3);
  pk2.pack("name"); pk2.pack("Bob");
  pk2.pack("age");  pk2.pack(33);
  pk2.pack("hist");
  pk2.pack_array(2);
  pk2.pack(4); pk2.pack(5);

  write(fd, buf2.data(), buf2.size());

  close(fd);
  return 0;
}

Lesen Sie den Beispielcode

#include <msgpack.hpp>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
  static const size_t BUFSIZE = 4; //Wagen Sie es, die Puffergröße zu verkleinern
  int rc;
  char buf[BUFSIZE];

  int fd = open("data.msg", O_RDONLY);

  msgpack::unpacker unpkr;
  while (0 < (rc = read(fd, buf, sizeof(buf)))) {
    unpkr.reserve_buffer(rc);
    memcpy(unpkr.buffer(), buf, rc);
    unpkr.buffer_consumed(rc);

    msgpack::object_handle result;
    while (unpkr.next(result)) {
      const msgpack::object &obj = result.get();

      if (obj.type == msgpack::type::MAP) {
        printf("{\n");
        msgpack::object_kv* p(obj.via.map.ptr);

        for(msgpack::object_kv* const pend(obj.via.map.ptr + obj.via.map.size);
            p < pend; ++p) {

          std::string key;
          p->key.convert(key);

          if (key == "name") {
            std::string value;
            p->val.convert(value);
            printf("  %s: %s,\n", key.c_str(), value.c_str());
          }

          if (key == "age") {
            int value;
            p->val.convert(value);
            printf("  %s: %d,\n", key.c_str(), value);
          }

          if (key == "hist") {
            msgpack::object arr = p->val;
            printf ("  %s, [", key.c_str());
            for (int i = 0; i < arr.via.array.size; i++) {
              int value;
              arr.via.array.ptr[i].convert(value);

              printf("%d, ", value);
            }
            printf ("],\n");
          }
        }

        printf("}\n");
      }

      result.zone().reset();
    }
  }

  return 0;
}

Übrigens, wenn Sie das msgpack :: object-Format in ostream ( std :: cout usw.) werfen, wird das Format ohne Erlaubnis formatiert und angezeigt, aber es ist wie oben beschrieben mühsam, den Wert programmgesteuert abzurufen. Das Verfahren wird als Beispiel beschrieben.

Recommended Posts

Empfehlung zur Datenanalyse mit MessagePack
Datenanalyse mit xarray
Datenanalyse mit Python-Pandas
[Python] [Word] [python-docx] Einfache Analyse von Diff-Daten mit Python
Analyse der Messdaten (2) -Hydrobacter und Anpassung, lmfit Empfehlung-
Zeitreihenanalyse 3 Vorverarbeitung von Zeitreihendaten
Empfehlungs-Tutorial mit Assoziationsanalyse (Konzept)
Datenverarbeitung 2 Analyse verschiedener Datenformate
Aufbau eines Empfehlungssystems mit Mundpropaganda doc2vec
Empfehlungs-Tutorial mit Assoziationsanalyse (Python-Implementierung)
Erstellen einer Datenanalyseanwendung mit Streamlit
Empfehlung von Altair! Datenvisualisierung mit Python
Kenntnis der Verwendung der Aurora Severless Data API
Datenanalyse Python
Analysieren Sie die Mundpropaganda-Daten von Karriere-Change-Meetings mithilfe von Deep Learning emotional
Datenanalyse Titanic 1
Ich habe versucht, eine Clusteranalyse von Kunden anhand von Kaufdaten durchzuführen
Zeitvariationsanalyse von Schwarzen Löchern mit Python
[Pandas] Grundlagen der Verarbeitung von Datumsdaten mit dt
Einführungsstudie zur Python-Ausgabe von Verkaufsdaten mit tapple-
Aufgezeichnete Umgebung für die Datenanalyse mit Python
Überprüfen Sie den Status der Daten mit pandas_profiling
Scraping der Gewinndaten von Zahlen mit Docker
Eine Einführung in die Datenanalyse mit Python - Um die Anzahl der Videoansichten zu erhöhen -
Datenanalyse mit Python 2
Erläuterung des Konzepts der Regressionsanalyse mit Python Teil 2
Zusammenfassung der statistischen Datenanalysemethoden mit Python, die im Geschäftsleben verwendet werden können
Analyse von Finanzdaten durch Pandas und deren Visualisierung (1)
Big-Data-Analyse mit dem Datenflusskontroll-Framework Luigi
Datenbereinigung 2 Datenbereinigung mit DataFrame
Datenbereinigung mit Python
Analyse der Messdaten ①-Memorandum of Scipy Fitting-
Geschichte der Bildanalyse von PDF-Dateien und Datenextraktion
Erläuterung des Konzepts der Regressionsanalyse mit Python Teil 1
[In-Database Python Analysis Tutorial mit SQL Server 2017] Schritt 4: Feature-Extraktion von Daten mit T-SQL
Ich habe versucht, die API von Sakenowa Data Project zu verwenden
Vorverarbeitung von Präfekturdaten
Orthologe Analyse mit OrthoFinder
Grundlagen der Regressionsanalyse
Beispiel für die Verwendung von Lambda
Auswahl der Messdaten
Datenanalyse mit Python
[Technisches Buch] Einführung in die Datenanalyse mit Python -1 Kapitel Einführung-
Analyse der Lebensdauer der Technologie mit Qiita-Artikeldaten ~ Überlebenszeitanalyse mithilfe des Inhaltsprotokolls ~
Erstellen Sie sofort ein Diagramm mit 2D-Daten mit der matplotlib von Python
Empfehlung von Jupyter Notebook, einer Codierungsumgebung für Datenwissenschaftler
Lassen Sie uns die Analyse der sinkenden Daten der Titanic so durchführen
Erster Schritt der Datenanalyse (Anzahl der Daten, Tabellenanzeige, fehlende Werte)
Spannungsanalyse des Torus unter Innendruck unter Verwendung eines axialsymmetrischen Spannungsanalyseprogramms
Datenanalyse basierend auf den Wahlergebnissen der Gouverneurswahl von Tokio (2020)
[Einführung] Künstliche Satellitendatenanalyse mit Python (Google Colab-Umgebung)
Ich habe versucht, scRNA-seq-Daten mithilfe der topologischen Datenanalyse (TDA) zu analysieren.
Mein Python-Datenanalyse-Container
Mehrdimensionale Datenanalysebibliothek xarray
Implementierung von TF-IDF mit Gensim
Python für die Datenanalyse Kapitel 4
Experiment zur Optimierung der Tensorflow-Daten
Wählen Sie Features mit Textdaten aus