# -*- coding: utf-8 -*-
"""
Implements processing techniques applied to bids before
mechanisms can use them
"""
import numpy as np
import pandas as pd
from pymarket.bids import BidManager
from collections import OrderedDict
[docs]def new_player_id(index):
"""Helper function for merge_same_price.
Creates a function that returns consecutive integers.
Parameters
-----------
index: int
First identifier to use for the
new fake players
Returns
-------
Callable : function
Function that maps a list
of user ids into a new user id.
Examples
----------
>>> id_gen = new_player_id(6)
>>> id_gen([3])
3
>>> id_gen([5])
5
>>> id_gen([0, 1])
6
>>> id_gen([2, 4])
7
"""
new_player_id.index = index
def new_id(users):
"""
Generates a unique identifier for a
list of users. If the list has
only one user, then the id is mantained
else, a new user id is created for the
whole list.
Parameters
----------
users: list of int
List of 1 or more user's identifiers.
Precondition: all elements of users
are smaller than index.
Returns
-------
int
The old identifier if in the list
there was only one player
and or the next new consecutive
identifier if there where more
than one.
"""
#nonlocal index
if len(users) > 1:
new_index = new_player_id.index
new_player_id.index += 1
else:
new_index = users[0]
return new_index
return new_id
[docs]def merge_same_price(df, prec=5):
"""
Process a collection of bids by merging in each
side (buying or selling) all players with the same
price into a new user with their aggregated quantity
Parameters
----------
df : pd.DataFrame
Collection of bids to process
prec: float
Number of digits to use after the comma
while comparing floating point prices
as equal.
Returns
-------
dataframe_new: pd.DataFrame
The new collection of bids where
players with the same price have
been merged into one.
final_maping : dict
Maping from new bids index to the
old bids index.
Examples
---------
>>> bm = BidManager()
>>> bm.add_bid(0.3, 1, 0)
0
>>> bm.add_bid(0.7, 1, 1)
1
>>> bm.add_bid(2, 1, 2, False)
2
>>> bm.add_bid(1, 2.444446, 3, False)
3
>>> bm.add_bid(3, 2.444447, 4, False)
4
>>> bm.get_df()
quantity price user buying time divisible
0 0.3 1.000000 0 True 0 True
1 0.7 1.000000 1 True 0 True
2 2.0 1.000000 2 False 0 True
3 1.0 2.444446 3 False 0 True
4 3.0 2.444447 4 False 0 True
>>> bids, index = pm.merge_same_price(bm.get_df(), 5)
>>> bids
quantity price user buying time divisible
0 1.0 1.00000 5 True 0 True
1 2.0 1.00000 2 False 0 True
2 4.0 2.44445 6 False 0 True
>>> index
{0: [0, 1], 1: [2], 2: [3, 4]}
>>> mar = pm.Market()
>>> mar.accept_bid(250, 200, 0, True) # CleanRetail
0
>>> mar.accept_bid(300, 110, 1, True) # El4You
1
>>> mar.accept_bid(120, 100, 2, True) # EVcharge
2
>>> mar.accept_bid( 80, 90, 3, True) # QualiWatt
3
>>> mar.accept_bid( 40, 85, 4, True) # IntelliWatt
4
>>> mar.accept_bid( 70, 75, 1, True) # El4You
5
>>> mar.accept_bid( 60, 65, 0, True) # CleanRetail
6
>>> mar.accept_bid( 45, 40, 4, True) # IntelliWatt
7
>>> mar.accept_bid( 30, 38, 3, True) # QualiWatt
8
>>> mar.accept_bid( 35, 31, 4, True) # IntelliWatt
9
>>> mar.accept_bid( 25, 24, 0, True) # CleanRetail
10
>>> mar.accept_bid( 10, 21, 1, True) # El4You
11
>>> mar.accept_bid(120, 0, 5, False) # RT
12
>>> mar.accept_bid(50, 0, 6, False) # WeTrustInWind
13
>>> mar.accept_bid(200, 15, 7, False) # BlueHydro
14
>>> mar.accept_bid(400, 30, 5, False) # RT
15
>>> mar.accept_bid(60, 32.5, 8, False) # KøbenhavnCHP
16
>>> mar.accept_bid(50, 34, 8, False) # KøbenhavnCHP
17
>>> mar.accept_bid(60, 36, 8, False) # KøbenhavnCHP
18
>>> mar.accept_bid(100,37.5, 9, False) # DirtyPower
19
>>> mar.accept_bid(70, 39, 9, False) # DirtyPower
20
>>> mar.accept_bid(50, 40, 9, False) # DirtyPower
21
>>> mar.accept_bid(70, 60, 5, False) # RT
22
>>> mar.accept_bid(45, 70, 5, False) # RT
23
>>> mar.accept_bid(50, 100, 10, False) # SafePeak
24
>>> mar.accept_bid(60, 150, 10, False) # SafePeak
25
>>> mar.accept_bid(50, 200, 10, False) # SafePeak
26
>>> bids, index = pm.merge_same_price(mar.bm.get_df())
>>> mar.bm.get_df()
quantity price user buying time divisible
0 250 200.0 0 True 0 True
1 300 110.0 1 True 0 True
2 120 100.0 2 True 0 True
3 80 90.0 3 True 0 True
4 40 85.0 4 True 0 True
5 70 75.0 1 True 0 True
6 60 65.0 0 True 0 True
7 45 40.0 4 True 0 True
8 30 38.0 3 True 0 True
9 35 31.0 4 True 0 True
10 25 24.0 0 True 0 True
11 10 21.0 1 True 0 True
12 120 0.0 5 False 0 True
13 50 0.0 6 False 0 True
14 200 15.0 7 False 0 True
15 400 30.0 5 False 0 True
16 60 32.5 8 False 0 True
17 50 34.0 8 False 0 True
18 60 36.0 8 False 0 True
19 100 37.5 9 False 0 True
20 70 39.0 9 False 0 True
21 50 40.0 9 False 0 True
22 70 60.0 5 False 0 True
23 45 70.0 5 False 0 True
24 50 100.0 10 False 0 True
25 60 150.0 10 False 0 True
26 50 200.0 10 False 0 True
"""
id_gen = new_player_id(df.user.max() + 1)
columns = df.columns.copy()
df = df.copy().reset_index().rename(columns={'index': 'bid'})
buy = df.loc[df['buying'], :]
sell = df.loc[~df['buying'], :]
dataframes = [buy, sell]
agg_fun = {
'bid': list,
'user': list,
'quantity': sum,
'buying': lambda x: x.sample(1),
'time': lambda x: x.sample(1),
'divisible': lambda x: x.sample(1),
}
dataframe_new = []
user_to_bid = OrderedDict()
for df_ in dataframes:
rounded_prices = df_.price.apply(lambda x: np.round(x, prec))
df_new = df_.groupby(rounded_prices).agg(agg_fun).reset_index()
# print(df_new)
df_new.user = df_new.user.apply(id_gen)
#maping = df_new.set_index('user').bid.to_dict()
# for k, v in maping.items():
# user_to_bid[k] = v
dataframe_new.append(df_new)
dataframe_new = pd.concat(dataframe_new).reset_index(drop=True)
final_maping = dataframe_new.bid.to_dict()
# print(final_maping)
dataframe_new = dataframe_new[columns]
# print('-------------')
# print(dataframe_new)
#index_to_user = dataframe_new.user.to_dict()
#final_maping =
# for k, v in index_to_user.items():
# final_maping[k] = user_to_bid[v]
return dataframe_new, final_maping