Kapitel 3.1.2 überarbeitet, count-tsv.sh Script ergänzt
This commit is contained in:
parent
16248f19c9
commit
c31a88fddf
|
@ -58,38 +58,109 @@ Das Script lädt zunächst OpenRefine und den Python-Client in einen Unterordner
|
||||||
|
|
||||||
## Schritt 2: Spalten einheitlich sortieren (und nicht benötigte MARC-Felder löschen)
|
## Schritt 2: Spalten einheitlich sortieren (und nicht benötigte MARC-Felder löschen)
|
||||||
|
|
||||||
Prinzipiell könnten die TSV-Daten jetzt auch direkt in OpenRefine geladen werden, aber die Spalten wären dann nicht alphabetisch sortiert und es wären auch zahlreiche Spalten enthalten, die nur extrem selten (weniger als 10 Werte in 580.000 Datensätzen) belegt sind. Das macht die Arbeit mit den Daten unübersichtlich und langsam. Also sollten wir als erstes nicht benötigte Spalten löschen und die Spalten sortieren.
|
Schauen Sie sich die ersten Zeilen der TSV-Dateien mit ```head -n1 *.tsv``` an. Die verschiedenen Pakete enthalten sehr unterschiedliche Spalten und sie sind in unterschiedlicher Reihenfolge sortiert. Mit dem Befehl ```head -q -n1 *.tsv | tr "\t" "\n" | sort | uniq -c``` können Sie sich einen Überblick darüber verschaffen, wie oft eine Spalte in den verschiedenen TSV-Dateien vorkommt. Leider sind die Daten uneinheitlich codiert, so dass sehr viele unterschiedliche MARC-Felder belegt sind. Die daraus resultierende hohe Anzahl an Spalten stellt hohe Leistungsanforderungen an OpenRefine. Der Arbeitsspeicher wird vermutlich nicht ausreichen, um alle Daten in ein Projekt zu laden. Führen Sie die folgenden Schritte aus, um die Spalten einheitlich zu sortieren und die Anzahl der Felder zu reduzieren.
|
||||||
|
|
||||||
Wir nutzen dazu die Software [csvkit](https://csvkit.readthedocs.io).
|
### 2.1 Anzahl der Werte pro MARC-Feld zählen
|
||||||
|
|
||||||
Installation:
|
Download des Shell-Scripts:
|
||||||
* ```sudo apt-get install python-dev python-pip python-setuptools build-essential```
|
```
|
||||||
* ```pip install csvkit```
|
wget https://github.com/felixlohmeier/seminar-praxis-der-digitalen-bibliothek/raw/master/scripte/count-tsv.sh && chmod +x count-tsv.sh
|
||||||
|
```
|
||||||
|
|
||||||
Dateien zusammenführen:
|
Script starten:
|
||||||
* ```csvstack -t *.tsv > stacked.csv```
|
```
|
||||||
|
./count-tsv.sh output/*.tsv | tee felder.tsv
|
||||||
|
```
|
||||||
|
|
||||||
Spalten sortieren:
|
Das Script gibt Ihnen für jede Datei nach und nach die Belegung aller enthaltenen Felder aus. Sie werden feststellen, dass viele Felder kaum belegt sind. Die dritte Spalte gibt an, wie häufig das Feld mehrfachbelegt ist (d.h. wie häufig das Zeichen ```␟``` vorkommt, das wir in Kapitel 7.3, Schritt 7 als Trennzeichen für mehrfach belegte Felder festgelegt haben). Der letzte Teil des Befehls (```tee felder.tsv```) sorgt dafür, dass zusätzlich zu der Ausgabe auf der Kommandozeile die Ergebnisse in der Datei "felder.tsv" gespeichert wurden.
|
||||||
* ```columns=$(head -n1 stacked.csv | sort)```
|
|
||||||
* ```csvcut -c $columns stacked.csv > sorted.csv```
|
|
||||||
|
|
||||||
Spalten mit sehr vielen leeren Werten ausgeben:
|
### 2.2 Datei felder.tsv in OpenRefine öffnen
|
||||||
* ```csvstat --nulls```
|
|
||||||
* Sie können die [Dokumentation des MARC21 Formats](http://www.dnb.de/DE/Standardisierung/Formate/MARC21/marc21_node.html) konsultieren, um zu prüfen, ob Sie die Informationen aus den Spalten mit sehr vielen (>570.000) Null-Werten wirklich benötigen.
|
|
||||||
|
|
||||||
Nicht benötigte Spalten löschen (hier ein Vorschlag):
|
Erstellen Sie ein neues Projekt in Openrefine und laden Sie die Datei felder.tsv hoch. Bei rund 580.000 Datensätzen können wir vermutlich diejenigen Felder vernachlässigen, die weniger als 100x belegt sind.
|
||||||
* ```csvcut -C spalte1,spalte2 -x > hsh-ksf.csv```
|
|
||||||
|
|
||||||
|
Summen bilden:
|
||||||
|
* Sort by Name column (if not already sorted) and make sort permanent
|
||||||
|
* Blank Down on name column to remove duplicate values
|
||||||
|
* On Value column, do Edit Cells -> Merge multi-valued cells
|
||||||
|
* On same column, do Edit Cells -> Transform with a GREL expression of forEach(value.split(','),v,v.toNumber()).sum()
|
||||||
|
* Facet by Blank on Name column, and select True (ie blank rows)
|
||||||
|
* Use All -> Edit Rows -> Remove all matching rows to delete the redundant rows
|
||||||
|
|
||||||
|
Felder, die sehr selten belegt sind, löschen:
|
||||||
|
* Numeric facet
|
||||||
|
* Use All -> Edit Rows -> Remove all matching rows
|
||||||
|
|
||||||
|
### 2.3 Transformationsdatei für OpenRefine generieren
|
||||||
|
|
||||||
|
Wenn Sie die Funktion ```All / Edit Columns / Re-order / remove columns...``` über die grafische Oberfläche durchführen und anschließend die Funktion ```Undo / Redo / Extract ...``` aufrufen, können Sie sich anschauen, wie die Transformationsregel in JSON definiert ist. Diese ist sehr einfach aufgebaut und sieht ungefähr so aus (in diesem Beispiel werden nur die Spalten A, B, C erhalten):
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op": "core/column-reorder",
|
||||||
|
"description": "Reorder columns",
|
||||||
|
"columnNames": [
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"C"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Das ermöglicht uns mit ein paar Texttransformationen die Konfigurationsdatei automatisch zu generieren:
|
||||||
|
* Die Spalten müssen in die eckigen Klammern nach ```"columnNames":``` eingefügt werden.
|
||||||
|
* Die Spalten müssen von Anführungszeichen umschlossen sein.
|
||||||
|
* Zwischen den Spalten steht ein Komma (nach der letzten Spalte also keins!).
|
||||||
|
|
||||||
|
Wir generieren die Konfigurationsdatei mit der Templating-Funktion von OpenRefine:
|
||||||
|
* Löschen Sie alle Spalten bis auf die Erste (MARC-Feld)
|
||||||
|
* Löschen Sie alle nicht benötigten Felder (Zeilen). Je weniger Felder enthalten sind, desto übersichtlicher wird die weitere Bearbeitung in den folgenden Kapiteln und desto geringer wird der Bedarf an Arbeitsspeicher.
|
||||||
|
* Rufen Sie im Menü "Export" den Punkt Templating auf
|
||||||
|
* Geben Sie folgendes in die Felder ein...
|
||||||
|
|
||||||
|
Prefix:
|
||||||
|
|
||||||
|
Row Template:
|
||||||
|
|
||||||
|
Suffix:
|
||||||
|
|
||||||
|
Klicken Sie auf Export und speichern Sie die Datei im selben Ordner, in dem auch das Script openrefine-batch.sh liegt.
|
||||||
|
|
||||||
|
Alternativ können Sie die folgenden vorbereiteten Dateien verwenden. Hier sind zwei Beispielkonfigurationen:
|
||||||
|
|
||||||
|
1. Alle Felder: [3-1-2_all.json](openrefine/3-1-2_all.json)
|
||||||
|
2. Feldauswahl auf Basis von Zielschema [Dublin Core (unqualified)](http://www.loc.gov/marc/marc2dc.html): [3-1-2_minimal.json](openrefine/3-1-2_minimal.json)
|
||||||
|
|
||||||
|
### 2.4 Dateien erneut mit OpenRefine automatisiert verarbeiten
|
||||||
|
|
||||||
|
Geben Sie die folgenden Befehle im Terminal ein:
|
||||||
|
|
||||||
|
```
|
||||||
|
rm -f input/*
|
||||||
|
mv output/*.tsv input/
|
||||||
|
rm -rf output
|
||||||
|
rm -f config/*
|
||||||
|
wget https://github.com/felixlohmeier/seminar-praxis-der-digitalen-bibliothek/raw/master/openrefine/3-1-2_minimal.json -O config/3-1-2_minimal.json
|
||||||
|
./openrefine-batch.sh -a input -b config -c output -m 3G -R
|
||||||
|
```
|
||||||
|
|
||||||
## Schritt 3: Daten in OpenRefine laden
|
## Schritt 3: Daten in OpenRefine laden
|
||||||
|
|
||||||
Für das Laden der gesamten rund 580.000 Datensätze werden etwa XXX GB freier Arbeitsspeicher benötigt.
|
OpenRefine führt unterschiedliche Datenstrukturen sinnvoll zusammen. Wenn die Dateien unterschiedlich viele Spalten oder eine andere Reihenfolge der Spalten haben, so ist das kein Problem. OpenRefine nimmt alle Spalten der ersten Datei auf und belegt diese mit neuen Zeilen. Sobald in einer weiteren Datei eine neue Spalte auftaucht, die OpenRefine noch nicht bekannt ist, so wird diese hinten angehängt.
|
||||||
|
|
||||||
Starten Sie OpenRefine mit dem zusätzlichen Parameter ```-m 4G```, damit OpenRefine über mehr Speicher verfügen kann:
|
Für das Laden der gesamten rund 580.000 Datensätze werden etwa XXX GB freier Arbeitsspeicher benötigt. Starten Sie OpenRefine mit dem zusätzlichen Parameter ```-m 4G```, damit OpenRefine über mehr Speicher verfügen kann. Sollten Sie auf Ihrer virtuellen Maschine nicht über genügend freien Arbeitsspeicher verfügen, dann reduzieren Sie den Wert im Parameter ```-m``` und laden Sie nur einen Teil der Daten.
|
||||||
```
|
```
|
||||||
~/openrefine-2.7-rc.2/refine -m 4G
|
~/openrefine-2.7-rc.2/refine -m 4G
|
||||||
```
|
```
|
||||||
|
|
||||||
Sollten Sie auf Ihrer virtuellen Maschine nicht über genügend freien Arbeitsspeicher verfügen, dann reduzieren Sie den Wert im Parameter ```-m``` und laden Sie nur einen Teil der Daten.
|
Erstellen Sie ein neues Projekt und laden Sie die im vorigen Schritt erstellten TSV-Dateien aus dem Ordner ```output``` hoch.
|
||||||
|
* Create Project / Durchsuchen... / TSV Dateien auswählen / Next / Configure Parsing Options
|
||||||
|
* Parse data as CSV / TSV / separator-based files
|
||||||
|
* Checkbox "Store file source..." deaktivieren
|
||||||
|
* Projektnamen vergeben (z.B. "hsh-ksf" und Button "Create Project" drücken
|
||||||
|
|
||||||
Erstellen Sie ein neues Projekt und laden Sie die im vorigen Schritt präparierte CSV-Datei ```hsh-ksf.csv``` hoch. Damit haben Sie nun endlich alle Daten in einem einzelnen Projekt und die Spalten alphabetisch sortiert. Das ist die Grundlage, auf der das nächste Kapitel aufsetzt.
|
Wenden Sie die Transformationsdatei aus dem vorigen Schritt noch einmal an, damit die Spalten erneut und abschließend alphabetisch sortiert werden.
|
||||||
|
* Menü oben links "Undo / Redo" aufrufen und Button "Apply..." drücken. Den Inhalt aus der Datei [3-1-2_minimal.json](openrefine/3-1-2_minimal.json) in die Zwischenablage kopieren und in das Textfeld von "Apply" einfügen und Button "Perform Operations" drücken.{%ends%}
|
||||||
|
|
||||||
|
Damit haben Sie nun endlich alle Daten in einem einzelnen Projekt und die Spalten alphabetisch sortiert. Das ist die Grundlage, auf der das nächste Kapitel aufsetzt.
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Script zur Zählung von belegten Werten in TSV-Dateien
|
||||||
|
# Stand: 05.01.2017
|
||||||
|
# Nutzung: ./count-tsv.sh file.tsv
|
||||||
|
|
||||||
|
# Abfrage der Dateinamen
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "Bitte Dateinamen angeben!"
|
||||||
|
echo "Beispiel: ./count-tsv.sh file.tsv"
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
files=($*)
|
||||||
|
printf '%s\t%s\t%s\n' MARC-Feld Vorkommen Mehrfachbelegung
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Schleife für mehrere Dateien
|
||||||
|
for file in "${files[@]}"; do
|
||||||
|
|
||||||
|
# Spaltennamen erfassen
|
||||||
|
readarray -t columns < <(head -q -n1 ${file} | tr '\t' '\n' | cat)
|
||||||
|
|
||||||
|
# Belegte Zellen in Spalten zählen und ausgeben
|
||||||
|
number=1
|
||||||
|
for column in "${columns[@]}"; do
|
||||||
|
printf '%s\t%s\t%s\n' "${column}" $(cut -d$'\t' -f ${number} ${file} | grep -v '^$' | wc -l) $(cut -d$'\t' -f ${number} ${file} | grep '␟' | wc -l)
|
||||||
|
number=$(($number+1))
|
||||||
|
done
|
||||||
|
done
|
Loading…
Reference in New Issue