Strings

The process of cleaning data for analysis often requires working with text, for example, to correct typos, convert to standard nomenclature and resolve ambiguous labels. In some statistical fields that deal with (say) processing electronic medical records, information science or recommendations based on user feedback, text must be processed before analysis - for example, by converting to a bag of words.

We will use a whimsical example to illustrate Python tools for munging text data using string methods and regular expressions. Finally, we will see how to format text data for reporting.

Get “Through the Looking Glass”

import requests

try:
    with open('looking_glass.txt') as f:
        text = f.read()
except IOError:
    url = 'http://www.gutenberg.org/cache/epub/12/pg12.txt'
    res = requests.get(url)
    text = res.text
    with open('looking_glass.txt', 'w') as f:
        f.write(str(text))

Slice to get Jabberwocky

start = text.find('JABBERWOCKY')
text[start:start+2000]
"JABBERWOCKYrnrn     'Twas brillig, and the slithy tovesrn      Did gyre and gimble in the wabe;rn     All mimsy were the borogoves,rn      And the mome raths outgrabe.rnrn     'Beware the Jabberwock, my son!rn      The jaws that bite, the claws that catch!rn     Beware the Jubjub bird, and shunrn      The frumious Bandersnatch!'rnrn     He took his vorpal sword in hand:rn      Long time the manxome foe he sought--rn     So rested he by the Tumtum tree,rn      And stood awhile in thought.rnrn     And as in uffish thought he stood,rn      The Jabberwock, with eyes of flame,rn     Came whiffling through the tulgey wood,rn      And burbled as it came!rnrn     One, two! One, two! And through and throughrn      The vorpal blade went snicker-snack!rn     He left it dead, and with its headrn      He went galumphing back.rnrn     'And hast thou slain the Jabberwock?rn      Come to my arms, my beamish boy!rn     O frabjous day! Callooh! Callay!'rn      He chortled in his joy.rnrn     'Twas brillig, and the slithy tovesrn      Did gyre and gimble in the wabe;rn     All mimsy were the borogoves,rn      And the mome raths outgrabe.rnrnrn'It seems very pretty,' she said when she had finished it, 'but it'srnRATHER hard to understand!' (You see she didn't like to confess, evenrnto herself, that she couldn't make it out at all.) 'Somehow it seemsrnto fill my head with ideas--only I don't exactly know what they are!rnHowever, SOMEBODY killed SOMETHING: that's clear, at any rate--'rnrn'But oh!' thought Alice, suddenly jumping up, 'if I don't make haste Irnshall have to go back through the Looking-glass, before I've seen whatrnthe rest of the house is like! Let's have a look at the garden first!'rnShe was out of the room in a moment, and ran down stairs--or, at least,rnit wasn't exactly running, but a new invention of hers for getting downrnstairs quickly and easily, as Alice said to herself. She just kept therntips of her fingers on the hand-rail, and floated gently down withoutrneven"
end = text.find('It seems very pretty', start)
poem = text[start:end]
poem
"JABBERWOCKYrnrn     'Twas brillig, and the slithy tovesrn      Did gyre and gimble in the wabe;rn     All mimsy were the borogoves,rn      And the mome raths outgrabe.rnrn     'Beware the Jabberwock, my son!rn      The jaws that bite, the claws that catch!rn     Beware the Jubjub bird, and shunrn      The frumious Bandersnatch!'rnrn     He took his vorpal sword in hand:rn      Long time the manxome foe he sought--rn     So rested he by the Tumtum tree,rn      And stood awhile in thought.rnrn     And as in uffish thought he stood,rn      The Jabberwock, with eyes of flame,rn     Came whiffling through the tulgey wood,rn      And burbled as it came!rnrn     One, two! One, two! And through and throughrn      The vorpal blade went snicker-snack!rn     He left it dead, and with its headrn      He went galumphing back.rnrn     'And hast thou slain the Jabberwock?rn      Come to my arms, my beamish boy!rn     O frabjous day! Callooh! Callay!'rn      He chortled in his joy.rnrn     'Twas brillig, and the slithy tovesrn      Did gyre and gimble in the wabe;rn     All mimsy were the borogoves,rn      And the mome raths outgrabe.rnrnrn'"
print(poem)
JABBERWOCKY

     'Twas brillig, and the slithy toves
      Did gyre and gimble in the wabe;
     All mimsy were the borogoves,
      And the mome raths outgrabe.

     'Beware the Jabberwock, my son!
      The jaws that bite, the claws that catch!
     Beware the Jubjub bird, and shun
      The frumious Bandersnatch!'

     He took his vorpal sword in hand:
      Long time the manxome foe he sought--
     So rested he by the Tumtum tree,
      And stood awhile in thought.

     And as in uffish thought he stood,
      The Jabberwock, with eyes of flame,
     Came whiffling through the tulgey wood,
      And burbled as it came!

     One, two! One, two! And through and through
      The vorpal blade went snicker-snack!
     He left it dead, and with its head
      He went galumphing back.

     'And hast thou slain the Jabberwock?
      Come to my arms, my beamish boy!
     O frabjous day! Callooh! Callay!'
      He chortled in his joy.

     'Twas brillig, and the slithy toves
      Did gyre and gimble in the wabe;
     All mimsy were the borogoves,
      And the mome raths outgrabe.


'
print(poem.title())
Jabberwocky

     'Twas Brillig, And The Slithy Toves
      Did Gyre And Gimble In The Wabe;
     All Mimsy Were The Borogoves,
      And The Mome Raths Outgrabe.

     'Beware The Jabberwock, My Son!
      The Jaws That Bite, The Claws That Catch!
     Beware The Jubjub Bird, And Shun
      The Frumious Bandersnatch!'

     He Took His Vorpal Sword In Hand:
      Long Time The Manxome Foe He Sought--
     So Rested He By The Tumtum Tree,
      And Stood Awhile In Thought.

     And As In Uffish Thought He Stood,
      The Jabberwock, With Eyes Of Flame,
     Came Whiffling Through The Tulgey Wood,
      And Burbled As It Came!

     One, Two! One, Two! And Through And Through
      The Vorpal Blade Went Snicker-Snack!
     He Left It Dead, And With Its Head
      He Went Galumphing Back.

     'And Hast Thou Slain The Jabberwock?
      Come To My Arms, My Beamish Boy!
     O Frabjous Day! Callooh! Callay!'
      He Chortled In His Joy.

     'Twas Brillig, And The Slithy Toves
      Did Gyre And Gimble In The Wabe;
     All Mimsy Were The Borogoves,
      And The Mome Raths Outgrabe.


'
poem.count('the')
15
print(poem.replace('the', 'XXX'))
JABBERWOCKY

     'Twas brillig, and XXX slithy toves
      Did gyre and gimble in XXX wabe;
     All mimsy were XXX borogoves,
      And XXX mome raths outgrabe.

     'Beware XXX Jabberwock, my son!
      The jaws that bite, XXX claws that catch!
     Beware XXX Jubjub bird, and shun
      The frumious Bandersnatch!'

     He took his vorpal sword in hand:
      Long time XXX manxome foe he sought--
     So rested he by XXX Tumtum tree,
      And stood awhile in thought.

     And as in uffish thought he stood,
      The Jabberwock, with eyes of flame,
     Came whiffling through XXX tulgey wood,
      And burbled as it came!

     One, two! One, two! And through and through
      The vorpal blade went snicker-snack!
     He left it dead, and with its head
      He went galumphing back.

     'And hast thou slain XXX Jabberwock?
      Come to my arms, my beamish boy!
     O frabjous day! Callooh! Callay!'
      He chortled in his joy.

     'Twas brillig, and XXX slithy toves
      Did gyre and gimble in XXX wabe;
     All mimsy were XXX borogoves,
      And XXX mome raths outgrabe.


'

Find palindromic words in poem if any

poem = poem.lower()
import string
string.punctuation
'!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~'
poem  = poem.translate(dict.fromkeys(map(ord, string.punctuation)))
poem
'jabberwockyrnrn     twas brillig and the slithy tovesrn      did gyre and gimble in the wabern     all mimsy were the borogovesrn      and the mome raths outgrabernrn     beware the jabberwock my sonrn      the jaws that bite the claws that catchrn     beware the jubjub bird and shunrn      the frumious bandersnatchrnrn     he took his vorpal sword in handrn      long time the manxome foe he soughtrn     so rested he by the tumtum treern      and stood awhile in thoughtrnrn     and as in uffish thought he stoodrn      the jabberwock with eyes of flamern     came whiffling through the tulgey woodrn      and burbled as it camernrn     one two one two and through and throughrn      the vorpal blade went snickersnackrn     he left it dead and with its headrn      he went galumphing backrnrn     and hast thou slain the jabberwockrn      come to my arms my beamish boyrn     o frabjous day callooh callayrn      he chortled in his joyrnrn     twas brillig and the slithy tovesrn      did gyre and gimble in the wabern     all mimsy were the borogovesrn      and the mome raths outgrabernrnrn'
words = poem.split()
words[:10]
['jabberwocky',
 'twas',
 'brillig',
 'and',
 'the',
 'slithy',
 'toves',
 'did',
 'gyre',
 'and']
def is_palindrome(word):
    return word == word[::-1]
{word for word in words if is_palindrome(word)}
{'did', 'o'}

Top 10 most frequent words

import collections
poem_counter = collections.Counter(words)
poem_counter.most_common(10)
[('the', 19),
 ('and', 14),
 ('he', 7),
 ('in', 6),
 ('my', 3),
 ('through', 3),
 ('jabberwock', 3),
 ('gyre', 2),
 ('mimsy', 2),
 ('mome', 2)]

Words that appear exactly twice.

[(k, v) for (k, v) in poem_counter.items() if v==2]
[('gyre', 2),
 ('mimsy', 2),
 ('mome', 2),
 ('wabe', 2),
 ('gimble', 2),
 ('it', 2),
 ('outgrabe', 2),
 ('all', 2),
 ('came', 2),
 ('with', 2),
 ('thought', 2),
 ('twas', 2),
 ('that', 2),
 ('vorpal', 2),
 ('were', 2),
 ('brillig', 2),
 ('slithy', 2),
 ('stood', 2),
 ('as', 2),
 ('did', 2),
 ('toves', 2),
 ('borogoves', 2),
 ('two', 2),
 ('beware', 2),
 ('went', 2),
 ('raths', 2),
 ('his', 2),
 ('one', 2)]

Trigrams

All possible sequences of 3 words in the poem.

list(zip(words[:], words[1:], words[2:]))[:10]
[('jabberwocky', 'twas', 'brillig'),
 ('twas', 'brillig', 'and'),
 ('brillig', 'and', 'the'),
 ('and', 'the', 'slithy'),
 ('the', 'slithy', 'toves'),
 ('slithy', 'toves', 'did'),
 ('toves', 'did', 'gyre'),
 ('did', 'gyre', 'and'),
 ('gyre', 'and', 'gimble'),
 ('and', 'gimble', 'in')]
import itertools as it
def window(x, n):
    """Sliding widnow of size n from iterable x."""
    s = (it.islice(x, i, None) for i in range(n))
    return zip(*s)
list(window(words, 3))[:10]
[('jabberwocky', 'twas', 'brillig'),
 ('twas', 'brillig', 'and'),
 ('brillig', 'and', 'the'),
 ('and', 'the', 'slithy'),
 ('the', 'slithy', 'toves'),
 ('slithy', 'toves', 'did'),
 ('toves', 'did', 'gyre'),
 ('did', 'gyre', 'and'),
 ('gyre', 'and', 'gimble'),
 ('and', 'gimble', 'in')]

Find words in poem that are over-represented

book = text
book = book.lower().translate(dict.fromkeys(map(ord, string.punctuation)))
book_counter = collections.Counter(book.split())
n = sum(book_counter.values())
book_freqs = {k: v/n for k, v in book_counter.items()}
n = sum(poem_counter.values())
stats = [(k, v, book_freqs.get(k,0)*n) for k, v in poem_counter.items()]
from pandas import DataFrame
df = DataFrame(stats, columns = ['word', 'observed', 'expected'])
df['score'] = (df.observed-df.expected)**2/df.expected
df = df.sort_values(['score'], ascending=False)
df.head(n=10)
word observed expected score
55 jabberwock 3 0.01557 572.045510
46 vorpal 2 0.01038 381.363673
69 beware 2 0.01038 381.363673
66 borogoves 2 0.01557 252.917766
43 twas 2 0.01557 252.917766
65 whiffling 1 0.00519 190.681837
39 tumtum 1 0.00519 190.681837
42 burbled 1 0.00519 190.681837
52 snickersnack 1 0.00519 190.681837
54 callooh 1 0.00519 190.681837

Encode and decode poem using a Caesar cipher

print(poem)
jabberwocky

     twas brillig and the slithy toves
      did gyre and gimble in the wabe
     all mimsy were the borogoves
      and the mome raths outgrabe

     beware the jabberwock my son
      the jaws that bite the claws that catch
     beware the jubjub bird and shun
      the frumious bandersnatch

     he took his vorpal sword in hand
      long time the manxome foe he sought
     so rested he by the tumtum tree
      and stood awhile in thought

     and as in uffish thought he stood
      the jabberwock with eyes of flame
     came whiffling through the tulgey wood
      and burbled as it came

     one two one two and through and through
      the vorpal blade went snickersnack
     he left it dead and with its head
      he went galumphing back

     and hast thou slain the jabberwock
      come to my arms my beamish boy
     o frabjous day callooh callay
      he chortled in his joy

     twas brillig and the slithy toves
      did gyre and gimble in the wabe
     all mimsy were the borogoves
      and the mome raths outgrabe

Encoding

def encode(text, k):
    table = dict(zip(map(ord, string.ascii_lowercase),
                              string.ascii_lowercase[k:] + string.ascii_lowercase[:k]))
    return text.translate(table)
cipher = encode(poem, 2)
print(cipher)
lcddgtyqema

     vycu dtknnki cpf vjg unkvja vqxgu
      fkf iatg cpf ikodng kp vjg ycdg
     cnn okoua ygtg vjg dqtqiqxgu
      cpf vjg oqog tcvju qwvitcdg

     dgyctg vjg lcddgtyqem oa uqp
      vjg lcyu vjcv dkvg vjg encyu vjcv ecvej
     dgyctg vjg lwdlwd dktf cpf ujwp
      vjg htwokqwu dcpfgtupcvej

     jg vqqm jku xqtrcn uyqtf kp jcpf
      nqpi vkog vjg ocpzqog hqg jg uqwijv
     uq tguvgf jg da vjg vwovwo vtgg
      cpf uvqqf cyjkng kp vjqwijv

     cpf cu kp whhkuj vjqwijv jg uvqqf
      vjg lcddgtyqem ykvj gagu qh hncog
     ecog yjkhhnkpi vjtqwij vjg vwniga yqqf
      cpf dwtdngf cu kv ecog

     qpg vyq qpg vyq cpf vjtqwij cpf vjtqwij
      vjg xqtrcn dncfg ygpv upkemgtupcem
     jg nghv kv fgcf cpf ykvj kvu jgcf
      jg ygpv icnworjkpi dcem

     cpf jcuv vjqw unckp vjg lcddgtyqem
      eqog vq oa ctou oa dgcokuj dqa
     q htcdlqwu fca ecnnqqj ecnnca
      jg ejqtvngf kp jku lqa

     vycu dtknnki cpf vjg unkvja vqxgu
      fkf iatg cpf ikodng kp vjg ycdg
     cnn okoua ygtg vjg dqtqiqxgu
      cpf vjg oqog tcvju qwvitcdg

Decoding

recovered = encode(cipher, -2)
print(recovered)
jabberwocky

     twas brillig and the slithy toves
      did gyre and gimble in the wabe
     all mimsy were the borogoves
      and the mome raths outgrabe

     beware the jabberwock my son
      the jaws that bite the claws that catch
     beware the jubjub bird and shun
      the frumious bandersnatch

     he took his vorpal sword in hand
      long time the manxome foe he sought
     so rested he by the tumtum tree
      and stood awhile in thought

     and as in uffish thought he stood
      the jabberwock with eyes of flame
     came whiffling through the tulgey wood
      and burbled as it came

     one two one two and through and through
      the vorpal blade went snickersnack
     he left it dead and with its head
      he went galumphing back

     and hast thou slain the jabberwock
      come to my arms my beamish boy
     o frabjous day callooh callay
      he chortled in his joy

     twas brillig and the slithy toves
      did gyre and gimble in the wabe
     all mimsy were the borogoves
      and the mome raths outgrabe

Using Regular Expressions

Find all words with a sequence of two or more identical letters e.g. “look”

import re
regex = re.compile(r'(\w*(\w)\2+\w*)', re.IGNORECASE | re.MULTILINE)
for match in regex.finditer(poem):
    print(match.group(2), match.group(1))
b jabberwocky
l brillig
l all
b jabberwock
o took
e tree
o stood
f uffish
o stood
b jabberwock
f whiffling
o wood
b jabberwock
o callooh
l callay
l brillig
l all

Convert the identical sequences to uppercase

def f(match):
    word, letter = match.groups()
    return word.replace(letter, letter.upper())

print(regex.sub(f, poem))
jaBBerwocky

     twas briLLig and the slithy toves
      did gyre and gimble in the wabe
     aLL mimsy were the borogoves
      and the mome raths outgrabe

     beware the jaBBerwock my son
      the jaws that bite the claws that catch
     beware the jubjub bird and shun
      the frumious bandersnatch

     he tOOk his vorpal sword in hand
      long time the manxome foe he sought
     so rested he by the tumtum trEE
      and stOOd awhile in thought

     and as in uFFish thought he stOOd
      the jaBBerwock with eyes of flame
     came whiFFling through the tulgey wOOd
      and burbled as it came

     one two one two and through and through
      the vorpal blade went snickersnack
     he left it dead and with its head
      he went galumphing back

     and hast thou slain the jaBBerwock
      come to my arms my beamish boy
     o frabjous day callOOh caLLay
      he chortled in his joy

     twas briLLig and the slithy toves
      did gyre and gimble in the wabe
     aLL mimsy were the borogoves
      and the mome raths outgrabe

Natural language processing

If you intend to perform statistical analysis on natural language, you should probably use NLTK to pre-process the text instead of using string methods and regular expressions. For example, a simple challenge is to first parse the paragraph below into sentences, then parse each sentence into words.

Paragraph from random Pubmed abstract.

para = """When compared with the control group no significant associations were found for the NS-PEecl group after adjustment of confounding variables. For the S-PEecl group, antiβ2GP1 IgG (OR 16.91, 95% CI 3.71-77.06) was associated, as well as age, obesity, smoking and multiparity. Antiβ2GP1-domain I IgG were associated with aCL, antiβ2GP1 and aPS/PT IgG in the three groups. aPS/PT IgG were associated with aCL IgG, and aPS/PT IgM were associated with aCL and antiβ2GP1 IgM in the three groups CONCLUSION: S-PEecl is a distinct entity from NS-PEecl and is mainly associated with the presence of antiβ2GP1 IgG. Antiβ2GP1 domain I correlate with other aPL IgG tests, and aPS/PT may be promising in patients in which LA tests cannot be interpreted."""

Naive splitting of sentences as anything separated by ., ! or ?

sep = re.compile(r'[\?\!\.]')
ss = sep.split(para)
for i, s in enumerate(ss, 1):
    print(i, ':', s, end='\n\n')
1 : When compared with the control group no significant associations were found for the NS-PEecl group after adjustment of confounding variables

2 :  For the S-PEecl group, antiβ2GP1 IgG (OR 16

3 : 91, 95% CI 3

4 : 71-77

5 : 06) was associated, as well as age, obesity, smoking and multiparity

6 :  Antiβ2GP1-domain I IgG were associated with aCL, antiβ2GP1 and aPS/PT IgG in the three groups

7 :  aPS/PT IgG were associated with aCL IgG, and aPS/PT IgM were associated with aCL and antiβ2GP1 IgM in the three groups CONCLUSION: S-PEecl is a distinct entity from NS-PEecl and is mainly associated with the presence of antiβ2GP1 IgG

8 :  Antiβ2GP1 domain I correlate with other aPL IgG tests, and aPS/PT may be promising in patients in which LA tests cannot be interpreted

9 :

Using NLTK

import nltk
ss_nltk = nltk.sent_tokenize(para)
for i, s in enumerate(ss_nltk, 1):
    print(i, ':', s, end='\n\n')
1 : When compared with the control group no significant associations were found for the NS-PEecl group after adjustment of confounding variables.

2 : For the S-PEecl group, antiβ2GP1 IgG (OR 16.91, 95% CI 3.71-77.06) was associated, as well as age, obesity, smoking and multiparity.

3 : Antiβ2GP1-domain I IgG were associated with aCL, antiβ2GP1 and aPS/PT IgG in the three groups.

4 : aPS/PT IgG were associated with aCL IgG, and aPS/PT IgM were associated with aCL and antiβ2GP1 IgM in the three groups CONCLUSION: S-PEecl is a distinct entity from NS-PEecl and is mainly associated with the presence of antiβ2GP1 IgG.

5 : Antiβ2GP1 domain I correlate with other aPL IgG tests, and aPS/PT may be promising in patients in which LA tests cannot be interpreted.

Naive parsing of the second sentence into words

s = ss_nltk[1]
s
'For the S-PEecl group, antiβ2GP1 IgG (OR 16.91, 95% CI 3.71-77.06) was associated, as well as age, obesity, smoking and multiparity.'
# remove punctuation and split on whit space
table = dict.fromkeys(map(ord, string.punctuation))
s.translate(table).split()
['For',
 'the',
 'SPEecl',
 'group',
 'antiβ2GP1',
 'IgG',
 'OR',
 '1691',
 '95',
 'CI',
 '3717706',
 'was',
 'associated',
 'as',
 'well',
 'as',
 'age',
 'obesity',
 'smoking',
 'and',
 'multiparity']

Using NLTK

text = nltk.word_tokenize(s)
text
['For',
 'the',
 'S-PEecl',
 'group',
 ',',
 'antiβ2GP1',
 'IgG',
 '(',
 'OR',
 '16.91',
 ',',
 '95',
 '%',
 'CI',
 '3.71-77.06',
 ')',
 'was',
 'associated',
 ',',
 'as',
 'well',
 'as',
 'age',
 ',',
 'obesity',
 ',',
 'smoking',
 'and',
 'multiparity',
 '.']

NLTK is a rich library for natural language processing

See http://www.nltk.org for details.

Tag tokens with part-of-speech labels

tagged_text = nltk.pos_tag(text)
tagged_text
[('For', 'IN'),
 ('the', 'DT'),
 ('S-PEecl', 'NNP'),
 ('group', 'NN'),
 (',', ','),
 ('antiβ2GP1', 'RB'),
 ('IgG', 'NNP'),
 ('(', '('),
 ('OR', 'NNP'),
 ('16.91', 'CD'),
 (',', ','),
 ('95', 'CD'),
 ('%', 'NN'),
 ('CI', 'NNP'),
 ('3.71-77.06', 'CD'),
 (')', ')'),
 ('was', 'VBD'),
 ('associated', 'VBN'),
 (',', ','),
 ('as', 'RB'),
 ('well', 'RB'),
 ('as', 'IN'),
 ('age', 'NN'),
 (',', ','),
 ('obesity', 'NN'),
 (',', ','),
 ('smoking', 'NN'),
 ('and', 'CC'),
 ('multiparity', 'NN'),
 ('.', '.')]
s
'For the S-PEecl group, antiβ2GP1 IgG (OR 16.91, 95% CI 3.71-77.06) was associated, as well as age, obesity, smoking and multiparity.'

A simplistic way to pick up nouns

[w for w, t in tagged_text if t.startswith('N')]
['S-PEecl',
 'group',
 'IgG',
 'OR',
 '%',
 'CI',
 'age',
 'obesity',
 'smoking',
 'multiparity']

String formatting

Selection

import math
stuff = ('bun', 'shoe', ['bee', 'door'], 2, math.pi, 0.05)
'One: {}, Two {}'.format(*stuff)
'One: bun, Two shoe'
'One: {0}, Two {1}'.format(*stuff)
'One: bun, Two shoe'
'One: {1}, Two {1}'.format(*stuff)
'One: shoe, Two shoe'
'One: {0}, Two {2[1]}'.format(*stuff)
'One: bun, Two door'

Formatting

'One: {0:^10s}, Two {1:_>15s}'.format(*stuff)
'One:    bun    , Two ___________shoe'
'One: {3}, Two {4}'.format(*stuff)
'One: 2, Two 3.141592653589793'
'One: {3:+10d}, Two {4:.4f}'.format(*stuff)
'One:         +2, Two 3.1416'
'One: {3:04d}, Two {4:.4g}'.format(*stuff)
'One: 0002, Two 3.142'
'One: {3:.4e}, Two {4:.4e}'.format(*stuff)
'One: 2.0000e+00, Two 3.1416e+00'
'One: {5:.2%}, Two {5:f}'.format(*stuff)
'One: 5.00%, Two 0.050000'

Old style formatting

'%s, %s, %a, %d, %.4f, %.2f' % stuff
"bun, shoe, ['bee', 'door'], 2, 3.1416, 0.05"

Formatting numpy arrays

import numpy as np
x = np.arange(1, 13).reshape(3,4)
x
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
np.set_printoptions(formatter={'int': lambda x: '%8.2f' % x})
x
array([[    1.00,     2.00,     3.00,     4.00],
       [    5.00,     6.00,     7.00,     8.00],
       [    9.00,    10.00,    11.00,    12.00]])
np.set_printoptions()
x
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])