Archive for the ‘Python / SciPy / pandas’ Category.

Parsing Emacs Orgmode files with Python

Here’s some experimental (alpha) code to parse Emacs Orgmode files. It’s far from complete, I only aim at parsing basic TODO strings with level (**), status (TODO, DONE), priority (#A, #B, #C), task and tags.

2016-09-03: It takes my actual orgmode file, so it’s working fine.

2016-09-04: I created a github repo, code updates will be added there, only: https://github.com/UweZiegenhagen/python-orgmode-parser

# -*- coding: utf-8 -*-
import re
 
def parseEmaceOrgmode(s):
    r = '^([\*]+)?\s?(TODO|PROGRESSING|FEEDBACK|VERIFY|POSTPONED|DELEGATED|CANCELLED|DONE)?\s?(\[#[A|B|C]\])?\s?(.*?)\s*(:(.*):)?$'    
    m = re.search(r,s)
    level = m.group(1)
    if (level is not None):
        level = len(level)
    prio = m.group(3)
    if (prio is not None):
        prio = prio[2:3]
    tags = []
    a = m.group(5)
    if a != None:
        b = len(a)-1
        a= a[1:b]
        a = a.split(':')
    tags.append(a)
    return(level, m.group(2), prio, m.group(4), tags)
 
with open("../orgmode.org", "r") as ins:
    for line in ins:
        level, status, priority, task, tags = parseEmaceOrgmode(line)
        if level is not None:        
            print('Level:', level)
            print('Status:', status)
            print('Priority:', priority)
            print('Task:', task)
            print('Tags:',tags,'\n\n')

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Ein einfaches Python-Beispiel für Klassen und Funktionen

Hier noch ein einfaches Python-Beispiel für Klassen und Funktionen, das ich vor ein paar Tagen geschrieben habe. Die Punkt-Klasse erhält eine entsprechende Funktion, um die Euklidische Distanz zu einem anderen Punkt zu bestimmen.

# -*- coding: utf-8 -*-
import math as m
 
class Point:
 
    def __init__(self,x,y):
        self.x = x
        self.y = y
 
    def calcEuclidDistanceToPoint(self,x,y):
        return m.sqrt(m.pow(self.x-x,2) + m.pow(self.y-y,2))
 
p1 = Point(0,0)
p2 = Point(1,1)
print(p2.calcEuclidDistanceToPoint(p1.x,p1.y))
runfile('euclidDistance.py', wdir='E:/Python')
1.4142135623730951

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Lineare Gleichungen lösen mit numpy

Hier ein kurzes Beispiel aus der numpy-Dokumentation, wie man mit Hilfe von numpy lineare Gleichungssysteme lösen kann:

Zu lösen sind folgende Gleichungen:

  • 3 * x0 + 1 * x1 = 9
  • 1 * x0 + 2 * x1 = 8

Die Koeffizienten kommen in die entsprechenden numpy-Arrays, dann ruft man linalg.solve auf:

import numpy as np
 
a = np.array([[3,1], [1,2]])
b = np.array([9,8])
x = np.linalg.solve(a, b)
print(x) # gibt [ 2.  3.]

pff

Den Plot habe ich mit LaTeX erstellt, siehe http://uweziegenhagen.de/?p=3516.

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Parallel LaTeXing with Python Threads

Based on an example from stackexchange I have created a small example on parallel TeX compilation.

# -*- coding: utf-8 -*-
"""
Created on 2016-07-06
Uwe Ziegenhagen
based on http://stackoverflow.com/questions/16181121/python-very-simple-multithreading-parallel-url-fetching-without-queue
"""
 
from multiprocessing.pool import ThreadPool
from time import time as timer
import os
 
files = ['test-01.tex','test-02.tex','test-03.tex','test-04.tex','test-05.tex',
'test-06.tex','test-07.tex','test-08.tex','test-09.tex','test-10.tex']
 
def compile_file(cfile):
	try:
		result = os.system('pdflatex -interaction=batchmode ' + cfile)
		return cfile, None
	except Exception as e:
		return cfile, e	
 
start = timer()
results = ThreadPool(8).imap_unordered(compile_file, files)
for cfile, error in results:
	if error is None:
		print("%r compiled in %ss" % (cfile, timer() - start))
	else:
		print("Error compiling %r: %s" % (cfile, error))
		print("Elapsed Time: %s" % (timer() - start,))
 
print('Gesamtzeit',timer() - start)

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Spalte aus Text-Datei extrahieren mit Python

Hier ein Quick & Dirty Code, um eine Spalte aus einer Text-Datei zu extrahieren. Geht auch mit AWK, aber wenn man nur Python hat…

def splitFileOneColumn(inputFile,outputFile,columnSeparator,column):
    with open(inputFile, 'r') as infile:
        with open(outputFile, 'w') as outfile:
            for line in infile:
                s = line.split(columnSeparator)
                outfile.write(s[column]+os.linesep) # '\r\n' on Windows, '\n' on Unix/Linux/Mac
            outfile.close()
    infile.close()

Bei Gelegenheit muss ich das mal um die Möglichkeit erweitern, n Spalten zu extrahieren.

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Daten aggregieren mit pandas

I recently came across a „challenge“ where I needed to combine various rows. Each row was identified by Key1 and Key2 and had two interesting columns, Foo and Bar. For each Key1 there may be a few Key2, for each Key2 n Foo/Bar entries. While all Foos are distinct per Key1 and Key2 the Bar column may appear j times.

The goal was to get a list of unique Bar items for each Key1/Key2 combination.

Key1 Key2 Foo Bar
0 C1 T1 a1 rc-1
1 C1 T1 a2 rc-1
2 C1 T1 a3 rc-1
3 C1 T1 a4 rc-1
4 C2 T2 b1 rc-1
5 C2 T2 b2 rc-2
6 C3 T3 c1 rc-3
7 C4 T4 d1 rc-4
8 C4 T4 d2 rc-5
9 C4 T4 d3 rc-4

The following Python code nicely did the job, thanks to http://stackoverflow.com/questions/17841149/pandas-groupby-how-to-get-a-union-of-strings

# -*- coding: utf-8 -*-
import pandas as pd
 
def unique(liste):
    """ takes a list of elements, separated by comma and returns sorted string of unique items separated by comma """
    a = liste.split(',')
    b = sorted(set(a))
    return ','.join(b)
 
df = pd.read_excel('groupb_Beispiel.xlsx')
print(df)
 
grouped = df.groupby(['Key1','Key2'],as_index=False)['Bar'].agg(lambda col: ','.join(col))
grouped = pd.DataFrame(grouped)
 
grouped['Unique'] = grouped['Bar'].apply(unique)
 
print(grouped)
 
grouped.to_excel('result.xlsx')
Key1 Key2 Bar Unique
0 C1 T1 rc-1,rc-1,rc-1,rc-1 rc-1
1 C2 T2 rc-1,rc-2 rc-1,rc-2
2 C3 T3 rc-3 rc-3
3 C4 T4 rc-4,rc-5,rc-4 rc-4,rc-5

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Folien zum Data Science Meetup vom 29.01.2016

Hier meine Folien zum Data Science Meetup vom 29.01.2016.

Pandas (PDF)

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Zeilen kombinieren mit pandas

Vor einiger Zeit hatte ich eine Excel-Datei zu bearbeiten, in der in einer Spalte die Spaltennamen, in einer anderen die korrespondieren Werte standen. Immer drei Zeilen bildeten den eigentlichen Datensatz. Mit wenigen Zeilen Pandas und cleverer Adressierung der Ergebnis-Zelle.

Spaltenname Wert
ColA Andi
ColB Berni
ColC Cesar
ColA Dorian
ColB Ernest
ColC Frank

 

import pandas as pd
 
# Lade die Daten
daten = pd.read_excel('combine.xlsx')
# Erstelle leeren Dataframe mit den Spaltennamen aus den Excelzeilen 
verarbeitet = pd.DataFrame(columns=['ColA','ColB','ColC'])
 
# Iteriere über die Daten
for i, row in daten.iterrows():
    # ganzzahliges Teilen, um die Zeile zu bestimmen
    # in die die Zelle gehört, Spalte ergibt sich aus dem Wert in 'Spalte'
    verarbeitet.loc[i // 3,row['Spalte']] = row['Wert']
 
print(verarbeitet)
ColA ColB ColC
0 Andi Berni Cesar
1 Dorian Ernest Frank

Nachtrag: Stephan vom Kölner Data Science Meetup hat mir noch einen alternativen Weg gezeigt:

import pandas as pd
 
data = {'A': ["cola", "colb", "colc", "cola", "colb", "colc"], "B": [1, 2, 3, 4, 5, 6]}
data = pd.DataFrame(data)
gb = data.groupby('A')
res = pd.DataFrame()
for key in gb.groups:
    res[key] = gb.get_group(key)['B'].values.flatten()
 
print(res)

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Buchungen auswerten mit Python Pandas

Ich bin ehrenamtlich Schatzmeister der Dingfabrik Köln e.V., als solcher muss ich auch schauen, welches Mitglied denn die Beiträge bezahlt hat. Mit Hilfe von Pandas lassen sich die Buchungsdaten sehr elegant aufbereiten.

Ausgangspunkt sind die folgenden Excel-Dateien

Mitglieder.xlsx

Enthält die Mitgliedsnummer, den Namen sowie die Mitgliedsart (F für Fördermitglied, O für Ordentlich, E für Ehemalig, etc.)

Klasse Name Mitgliedsart
1 Max Mustermann O

Buchungen.xlsx

Die Buchungen wurden aus Quicken 2015 nach Excel exportiert, die Datei muss leider noch manuell bearbeitet werden, da der Excel-Export von Quicken nicht sonderlich schön ist. Die relevante Kategorie ist in diesem Beispiel „Mitgliedsbeitrag“, Klasse enthält die zugewiesene Mitgliedsnummer.

Buchungstag Konto Vorgang Empfänger Verwendungszweck Kategorie Klasse Betrag
04.01.2016 Firmengirokonto Köln 3763   Buchungstext bla, bla Mitgliedsbeitrag 1 23,00

Diese beiden Dateien können wir jetzt mit Pandas verarbeiten.

import pandas as pd
import numpy as np
import time as t
 
# Anpassungen an der Pandas-Ausgabe
pd.set_option('display.float_format', lambda x: '%.2f' % x)
# http://stackoverflow.com/questions/11707586/python-pandas-widen-output-display
pd.set_option('display.height', 1000)
pd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)
 
# lies die Stammdaten aus Excel
mitglieder = pd.read_excel('Mitglieder.xlsx', 'Tabelle1')
# konvertier die Mitgliedsnummer in einen String
mitglieder['Klasse'] = mitglieder['Klasse'].apply(int).apply(str)
# Ehemalige Mitglieder interessieren nicht
mitglieder = mitglieder[mitglieder.Mitgliedsart.str.contains('A|F|O')]
 
# lies die Buchungen ein
buchungen = pd.read_excel('Buchungen.xlsx', 'Sheet')
# entferne alle Zeilen, die keinen 'Mitgliedbeitrag' enthalten
buchungen = buchungen[buchungen.Kategorie.str.contains('Mitgliedsbeitrag')]
 
# entferne Zeilen ohne Betrag oder Klasse
buchungen = buchungen[np.isfinite(buchungen['Betrag'])]
buchungen = buchungen[np.isfinite(buchungen['Klasse'])]
 
# Konvertiere den Buchungstag in ein Pandas-Datum
buchungen['Buchungstag'] = pd.to_datetime(buchungen['Buchungstag'],dayfirst=True,format='%d.%m.%Y') 
 
# Füge neue Spalten für Quartal und Monat hinzu
buchungen['Quartal'] = buchungen['Buchungstag'].dt.quarter
buchungen['Monat'] = buchungen['Buchungstag'].dt.month
 
# Wandle 'Klasse' von Float => Integer => String 
buchungen['Klasse'] = buchungen['Klasse'].apply(int).apply(str) 
 
# Führe einen right join durch, wir wollen auch die Datensätze von Mitgliedern haben, die noch aktiv sind, aber noch nichts bezahlt haben
buchungen = pd.merge(buchungen,mitglieder, how='right', on=['Klasse', 'Klasse'])
 
# Durch den right Join haben wir jetzt einige NaN (Not a Number) Zellen, die wir durch 0.0 ersetzen
# Dadurch erzeugen wir Dummy Datensätze, die aber nicht stören
buchungen['Betrag'].fillna(value=0,inplace=True)
buchungen['Buchungstag'].fillna(value=pd.Timestamp('20160101'),inplace=True)
# Einen Eintrag für die Monatsspalte nehmen wir auch vor, darüber wird pivotisiert
buchungen['Monat'] = buchungen['Buchungstag'].dt.month
 
# Erstellung der Pivot-Table
pivotTable = pd.pivot_table(buchungen,dropna=False,margins=True,index=['Name'],values=['Betrag'],columns=['Monat'],aggfunc=np.sum)
 
print(pivotTable)
 
# Optional: Rausschreiben der Tabelle nach Excel
#pivotTable.to_excel('pivotisiert.xlsx')

Das Ergebnis, hier anonymisiert und bei Betrag nur jeweils 1.0 eingetragen, sieht dann so aus:

pivot

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website

Excel und Python Win32COM

Hier ein kleines Beispiel, wie man mittels COM eine Excel-Mappe aus Python heraus befüllt und die Excel-Instanz beendet.

from win32com import client
 
# http://stackoverflow.com/questions/10221150/cant-close-excel-completely-using-win32com-on-python
def close_excel_by_force(excel):
    import win32process
    import win32gui
    import win32api
    import win32con
    import time
 
    # Get the window's process id's
    hwnd = excel.Hwnd
    t, p = win32process.GetWindowThreadProcessId(hwnd)
    # Ask window nicely to close
    win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
    # Allow some time for app to close
    time.sleep(10)
    # If the application didn't close, force close
    try:
        handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p)
        if handle:
            win32api.TerminateProcess(handle, 0)
            win32api.CloseHandle(handle)
    except:
        pass
 
# Öffne Referenz zu Excel
excel = client.Dispatch("Excel.Application")
 
# Wir wollen sehen, was geschieht
excel.Visible= True
 
# Öffne eine bestehende Arbeitsmappe (im selben Verzeichnis)
wb = excel.Workbooks.Open('C:/Users/john/doe/win32test.xlsx')
 
# Wähle das erste Arbeitsblatt aus
ws = wb.Worksheets(1)
 
# Wähle alle Zellen aus
excel.Cells.Select()
# Entferne den Zellschutz
excel.Selection.Locked = False
# Wähle die Spalten B bis E aus
excel.Range("B:E").Select()
# setze den Zellschutz
excel.Selection.Locked = True
 
# Schütze das Sheet mit einem Passwort
ws.Protect("password", True, True)
 
# Speichere ab
wb.Save()
 
# Schließe die Mappe
wb.Close()
 
# Close Excel
excel.Quit()
wb = None
wbs = None
 
close_excel_by_force(excel)

Uwe

Uwe Ziegenhagen has been working with LaTeX for more than a decade. Besides TeX/LaTeX he likes to work with Python, Rasberry/Arduino and his digital camera.

More Posts - Website