Posts tagged ‘Pandas’

Mit Python suchen und ersetzen in CSV-Dateien (mit pandas)

Nachdem wir uns im letzten Artikel angeschaut hatten, wie man mit openpyxl Funktionen Felder in CSV-Dateien mit Werten aus Excel-Dateien ersetzen kann, heute nun die pandas Implementierung dessen.

Sie nutzt auch openpyxl zum Einlesen der Excel-Datei, da xlrd, das bisher von pandas genutzte Modul für Excel-Dateien, den Support für XLSX Formate eingestellt hat.

Die Arbeitsweise des Codes ist recht einfach. pandas liest die Datei, da die Tabelle nicht links oben anfängt, werden die erste Zeile und Spalte ignoriert und die Spalten passend benannt. Dann iterieren wird durch den Dataframe und ersetzen munter…

import pandas as pd
 
path = "python_test.xlsx"
df = pd.read_excel(path,engine='openpyxl',
                   sheet_name='Tabelle2',skiprows=1,
                   usecols={1,2},header=None)
 
df = df.rename(columns={1: "Key", 2: "Value"})
 
with open('Python_test.txt') as input_file:
    text = input_file.read()
 
    for index, row in df.iterrows():
        text = text.replace(row['Key'] ,str(row['Value']))
 
    with open('Python_test_output_pd.txt','w') as output_file:
        output_file.write(text)

Nordwind-DB mit Python abfragen (Python, pandas, MySQL)

Hier ein einfaches Beispiel, wie man die Daten aus der Nordwind-Datenbank in einen pandas Dataframe bekommt. Der originale Code stammt von https://pythontic.com/pandas/serialization/mysql und wurde auf meine Datenbank angepasst.

# -*- coding: utf-8 -*-
 
from sqlalchemy import create_engine
import pymysql
import pandas as pd
 
sqlEngine       = create_engine('mysql+pymysql://nwread:northwind@192.168.0.60/northwind', pool_recycle=3600)
dbConnection    = sqlEngine.connect()
frame           = pd.read_sql("select * from products", dbConnection);
 
pd.set_option('display.expand_frame_repr', False)
print(frame)
 
frame.to_excel('r:/abc.xlsx')
 
dbConnection.close()

Excel-Dateien schreiben mit Openpyxl: (Bedingte) Formatierung

This entry is Teil 6 von 6 in the series Openpyxl

Mit Openpyxl lassen sich auch Zellformatierungen und bedingte Formatierungen setzen. Das folgende Beispiel formatiert die ersten beiden Spalten grün, wenn der Zellwert „1“ beträgt und rot für alle anderen Inhalte. Die dritte Spalte wird mit blauem Hintergrund formatiert, hier jedoch ohne Bedingung.

import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.utils.cell import get_column_letter
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.worksheet.table import Table, TableStyleInfo
 
from openpyxl.styles import Color, PatternFill, Font, Border
from openpyxl.formatting.rule import ColorScaleRule, CellIsRule, FormulaRule, Rule
 
 
dataframe = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
rows = dataframe_to_rows(dataframe, index=False, header=True)
 
wb = Workbook()
ws = wb.active
 
for r_idx, row in enumerate(rows, 1):
    for c_idx, value in enumerate(row, 1):
        ws.cell(row=r_idx, column=c_idx, value=value)
 
# Set column widths based on title width or fixed number
widths = {}
for column in ws.columns:
    if column[0].value is None: # no column header => Fixed with
        widths[column[0].column] = 10.5
    else: # if column header is present => min width resp. maximum
        widths[column[0].column] = max(len(str(column[0].value)) * 1.45, 10.5)
 
ws.column_dimensions[get_column_letter(column[0].column)].width = widths[column[0].column]
 
# Insert formatted table from A1 to max column/max row
tab = Table(displayName="MeineTabelle", ref='A1:' + get_column_letter(ws.max_column) + str(ws.max_row))
style = TableStyleInfo(name="TableStyleLight9", showFirstColumn=False,
                       showLastColumn=False, showRowStripes=True, showColumnStripes=True)
tab.tableStyleInfo = style
ws.add_table(tab)
 
# conditional formatting
redFill = PatternFill(start_color='EE1111',end_color='EE1111',fill_type='solid')
greenFill = PatternFill(start_color='EE1111',end_color='11EE11',fill_type='solid')
ws.conditional_formatting.add('A2:B'+str(ws.max_row),CellIsRule(operator='equal', formula=[1], stopIfTrue=True, fill=greenFill))
ws.conditional_formatting.add('A2:B'+str(ws.max_row),CellIsRule(operator='notEqual', formula=[1], stopIfTrue=True, fill=redFill))
 
lightbluefill = PatternFill(start_color='CCCCFF',end_color='CCCCFF',fill_type='solid')
 
for rowNum in range(2, ws.max_row + 1):
    ws.cell(row=rowNum, column=3).fill = lightbluefill
 
wb.save('07.xlsx')
wb.close()

Excel-Dateien schreiben mit Openpyxl: Kalkulationstabelle erstellen

This entry is Teil 5 von 6 in the series Openpyxl

Mit Openpyxl lassen sich auch einfach Excel-Daten in Kalkulationstabellen umwandeln, die eine ansprechende Formatierung, Unterstützung bei Formeln und Filter mitbringen. Im folgenden Beispiel nutzen wir noch die Hilfsfunktion get_column_letter(ws.max_column) aus dem utils.cell Modul, um den Excel-Spaltenname für die entsprechenden Spalten zu bestimmen.

import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.utils.cell import get_column_letter
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.worksheet.table import Table, TableStyleInfo
 
 
dataframe = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
rows = dataframe_to_rows(dataframe, index=False, header=True)
 
wb = Workbook()
ws = wb.active
 
for r_idx, row in enumerate(rows, 1):
    for c_idx, value in enumerate(row, 1):
        ws.cell(row=r_idx, column=c_idx, value=value)
 
# Set column widths based on title width or fixed number
widths = {}
for column in ws.columns:
    if column[0].value is None: # no column header => Fixed with
        widths[column[0].column] = 10.5
    else: # if column header is present => min width resp. maximum
        widths[column[0].column] = max(len(str(column[0].value)) * 1.45, 10.5)
 
ws.column_dimensions[get_column_letter(column[0].column)].width = widths[column[0].column]
 
# Insert formatted table from A1 to max column/max row
tab = Table(displayName="MeineTabelle", ref='A1:' + get_column_letter(ws.max_column) + str(ws.max_row))
style = TableStyleInfo(name="TableStyleLight9", showFirstColumn=False,
                       showLastColumn=False, showRowStripes=True, showColumnStripes=True)
tab.tableStyleInfo = style
ws.add_table(tab)
 
wb.save('05.xlsx')
wb.close()

Excel-Dateien schreiben mit Openpyxl: Spaltenbreiten errechnen

This entry is Teil 4 von 6 in the series Openpyxl

Wir im letzten Teil erwähnt, lassen sich die Spaltenbreiten beim Export nach Excel auch errechnen. Dazu dient der Schnipsel von stackoverflow im folgenden Code. Ich habe den Code noch so abgewandelt, dass — wenn eine Spaltenüberschrift vorhanden ist — das Maximum aus dem Produkt der errechneten Breite und einem händisch festgelegten Faktor und einer fixen Zahl genutzt wird.

import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
 
dataframe = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
rows = dataframe_to_rows(dataframe, index=False, header=True)
 
wb = Workbook()
ws = wb.active
 
for r_idx, row in enumerate(rows, 1):
    for c_idx, value in enumerate(row, 1):
        ws.cell(row=r_idx, column=c_idx, value=value)
 
# Set column widths based on title width or fixed number
widths = {}
for column in ws.columns:
    if column[0].value is None: # no column header => Fixed with
        widths[column[0].column] = 10.5
    else: # if column header is present => min width resp. maximum
        widths[column[0].column] = max(len(str(column[0].value)) * 1.45, 10.5)
 
ws.column_dimensions[get_column_letter(column[0].column)].width = widths[column[0].column]
 
wb.save('04.xlsx')
wb.close()

Excel-Dateien schreiben mit Openpyxl: Spaltenbreiten manuell setzen

This entry is Teil 3 von 6 in the series Openpyxl

Mit openpyxl lassen sich auch die Spaltenbreiten für einzelne Spalten explizit festlegen. Dazu liefert das worksheet Objekt die Eigenschaft column_dimensions mit, die man einfach setzen kann. Dieses manuelle Setzen kann man auch weglassen, wenn man die Spaltenbreite errechnen lässt, dazu mehr im nächsten Teil.

import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
 
dataframe = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
rows = dataframe_to_rows(dataframe, index=False, header=True)
 
wb = Workbook()
ws = wb.active
 
for r_idx, row in enumerate(rows, 1):
    for c_idx, value in enumerate(row, 1):
        ws.cell(row=r_idx, column=c_idx, value=value)
 
ws.column_dimensions['A'].width = 5
ws.column_dimensions['B'].width = 10
ws.column_dimensions['C'].width = 15
 
wb.save('03.xlsx')
wb.close()

Excel-Dateien schreiben mit Openpyxl: Pandas Dataframes exportieren

This entry is Teil 2 von 6 in the series Openpyxl

Wichtiger als das manuelle Schreiben von Excel-Dateien ist für mich das Umwandeln von pandas Dataframes in Excel-Dateien.

Hier das passende Beispiel dazu, wie man einen Dataframe in eine Excel-Datei exportiert.

import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
 
dataframe = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
rows = dataframe_to_rows(dataframe, index=False, header=True)
 
wb = Workbook()
ws = wb.active
 
for r_idx, row in enumerate(rows, 1):
    for c_idx, value in enumerate(row, 1):
        ws.cell(row=r_idx, column=c_idx, value=value)
 
wb.save('02.xlsx')
wb.close()

Russische Bauernmultiplikation mit Python

Durch eine SX Frage bin ich auf das Verfahren der „Russischen Bauernmultiplikation“ gestoßen, mit der man ohne Multiplikation ganzzahlige Zahlen miteinander multiplizieren kann. Just for Fun hier die Python-Implementierung:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 18 10:04:40 2017
 
@author: Uwe Ziegenhagen
"""
import pandas as pd
from math import floor
 
def russianPeasantMultiply(a, b):
    assert a > 1
    assert b > 0    
    data = pd.DataFrame([[a, b]], columns=list('ab'))
    while a > 1:
        a = floor(a/2)
        b = b + b
        data.loc[len(data)]=[a, b]
    data = data[data['a'] % 2 == 1]    
    return(data.b.sum())
 
print(russianPeasantMultiply(63, 17))

Ohne pandas geht es sicher auch, aber pandas macht es etwas einfacher…

Daten arrangieren mit pandas melt

Hier ein kurzes Beispiel, wie man mittels melt bestimmte Daten in die richtige Form bekommt.

Ausgangspunkt ist der folgende Datensatz:

Zum Auswerten ist der nicht optimal, ich möchte die Monatswerte gern untereinander haben. Mittels melt geht das ganz einfach:

# -*- coding: utf-8 -*-
 
import pandas as pd
 
data = pd.read_excel('meltdata.xlsx')
 
print(data.shape[1], 'columns and', data.shape[0], 'rows')
 
print(list(data))
 
melted = pd.melt(data, id_vars=['Name', 'ColumnB', 'ColumnC'], 
                 value_vars=['Januar', 'Februar', 'März', 'April', 'Mai', 
                 'Juni', 'Juli', 'August', 'September', 'Oktober', 
                 'November', 'Dezember'])
 
print(melted)
      Name    ColumnB ColumnC   variable  value
0 Donald 1978-09-03 Hello Januar 98
1 Micky 1945-05-04 World Januar 29
2 Minnie 1946-07-05 Foo Januar 57
3 Pluto 1998-07-08 Bar Januar 28
4 Donald 1978-09-03 Hello Februar 31
5 Micky 1945-05-04 World Februar 41
6 Minnie 1946-07-05 Foo Februar 24
...

Slides from my 2016 Froscon Presentation „Using Python for Scientific Research“

Here are my slides from the Froscon 2016 presentation „Using Python for Scientific Research“.

Slides: Froscon_Slides_2016

Video: Video Recording (The screen was flickering most of the time, pretty annoying and distracting)

I will continously update and expand this presentation during the next months, if you want to receive updates follow the GitHub repository: https://github.com/UweZiegenhagen/2016-Python-Data-Analysis-Slides/