def monte_carlo(df, n=1000, verbose=False):
"""Take a DataFrame of probabilities (in range 0..1) for outcomes (in columns)
for each case (in rows), and conduct a Monte Carlo simulation.
Return a tuple of three DataFrames. The first is the raw simulation results.
The second is the outcome tally of those results for each simulation.
The third DataFrame returned is a binned summary of the tally for each outcome.
"""
# contract
assert((df.sum(axis=1) == 1.0).all)
# monte carlo - we do this by rows to use the pandas.cut() function
print('Doing the MC simulation ...')
simulation = {}
for (name, series) in df.iterrows():
# for each case MC similate n outcomes ...
if verbose:
print(name)
# set up this simulation
votes = np.random.rand(n)
s = series[series > 0.0]
labels = s.index.tolist()
cuts = [0.0] + s.cumsum().tolist()
# and simulate
simulation[name] = pd.cut(votes, bins=cuts, labels=labels, precision=7)
# Take the dictionary of case outcomes above,
# Put them into a DataFrame as columns.
# So that we can subsequently tally rows of simulation outcomes below.
simulation = pd.DataFrame(simulation)
# tally the results - for each simulation
print('Tallying the results of the MC simulation ...')
tally = {}
for (name, series) in simulation.iterrows():
tally[name] = series.value_counts()
tally = pd.DataFrame.from_dict(tally, orient='index')
tally.fillna(0, inplace=True)
tally = tally.astype(int)
# - summarise into value_counts
print('Summarising the tally of the MC simulation ...')
summary = {}
for (name, series) in tally.iteritems():
summary[name] = series.value_counts()
summary = pd.DataFrame(summary)
summary.fillna(0, inplace=True)
summary = summary.astype(int)
# - return simulation summary
return (simulation, tally, summary)
Showing posts with label python. Show all posts
Showing posts with label python. Show all posts
Sunday, 26 June 2016
Monte Carlo simulation
Yesterday I coded a quick and dirty Monte-Carlo simulation function. Here it is.
Sunday, 19 June 2016
Combining two lists into a human readable string
I wanted to list the odds I had scraped from a website as a comma delimited string list.
The first task was to join the party names with their odds.
The second challenge was to bring that list into a delimited string.
It took me a few goes to land the ideal approach
Let's start with some play data
My first go at combining the party names with their odds.
My second attempt
My third attempt - this looks about right
Now, to get that into a delimited string. Voila!
The first task was to join the party names with their odds.
The second challenge was to bring that list into a delimited string.
It took me a few goes to land the ideal approach
Let's start with some play data
names = ['Alpha', 'Beta', 'Gamma', 'Delta'] amounts = [1.20, 4.50, 151, 19.50]
My first go at combining the party names with their odds.
In [19]: [' '.join([a, str(b)]) for a, b in zip(names, amounts)] Out[19]: ['Alpha 1.2', 'Beta 4.5', 'Gamma 151', 'Delta 19.5']
My second attempt
In [20]: [' '.join([a, '$'+ str(b)]) for a, b in zip(names, amounts)] Out[20]: ['Alpha $1.2', 'Beta $4.5', 'Gamma $151', 'Delta $19.5']
My third attempt - this looks about right
In [21]: ['{} ${:.2f}'.format(a, b) for a, b in zip(names, amounts)]
Out[21]: ['Alpha $1.20', 'Beta $4.50', 'Gamma $151.00', 'Delta $19.50']
Now, to get that into a delimited string. Voila!
In [22]: ', '.join(['{} ${:.2f}'.format(a, b) for a, b in zip(names, amounts)])
Out[22]: 'Alpha $1.20, Beta $4.50, Gamma $151.00, Delta $19.50'
Subscribe to:
Posts (Atom)