I am simulating a SQL query with the following values:
rows = [(1, '2021/04', 'Shop 2', 341227.53), (2, '2021/05', 'Shop 2', 315447.24), (3, '2021/06', 'Shop 1', 1845662.35), (4, '2021/04', 'Shop 2', 21487.63), (5, '2021/05', 'Shop 1', 1489774.16), (6, '2021/06', 'Shop 1', 52489.35), (7, '2021/04', 'Shop 1', 154552.82), (8, '2021/05', 'Shop 2', 6548.49), (9, '2021/06', 'Shop 2', 387779.49)]
I want to build a dictionary of a ‘window’ function. It should partition on the third column (ex value: ‘shop1’) and order by the second column (ex value: ‘2021/06’).
So, it should look like this:
{
'Shop 1': ['2021/04', '2021/05', ...],
'Shop 2': [...],
...
}
Is there a way to do that such that I could define a lambda function taking two arguments, for example:
window_func = lambda partition_func, order_func: ...
The above partition_func would be item[2] and the order_func would be item[3].
>Solution :
Try:
from itertools import groupby
from operator import itemgetter
rows = [
(1, "2021/04", "Shop 2", 341227.53),
(2, "2021/05", "Shop 2", 315447.24),
(3, "2021/06", "Shop 1", 1845662.35),
(4, "2021/04", "Shop 2", 21487.63),
(5, "2021/05", "Shop 1", 1489774.16),
(6, "2021/06", "Shop 1", 52489.35),
(7, "2021/04", "Shop 1", 154552.82),
(8, "2021/05", "Shop 2", 6548.49),
(9, "2021/06", "Shop 2", 387779.49),
]
window_func = lambda partition_func, order_func: lambda x: {
k: [order_func(v) for v in g]
for k, g in groupby(
sorted(x, key=lambda v: (partition_func(v), order_func(v))), partition_func
)
}
fn = window_func(itemgetter(2), itemgetter(1))
print(fn(rows))
Prints:
{
"Shop 1": ["2021/04", "2021/05", "2021/06", "2021/06"],
"Shop 2": ["2021/04", "2021/04", "2021/05", "2021/05", "2021/06"],
}
EDIT: To get list of rows in the output:
window_func = lambda partition_func, order_func: lambda x: {
k: list(g)
for k, g in groupby(
sorted(x, key=lambda v: (partition_func(v), order_func(v))), partition_func
)
}
fn = window_func(itemgetter(2), itemgetter(1))
print(fn(rows))
Prints:
{
"Shop 1": [
(7, "2021/04", "Shop 1", 154552.82),
(5, "2021/05", "Shop 1", 1489774.16),
(3, "2021/06", "Shop 1", 1845662.35),
(6, "2021/06", "Shop 1", 52489.35),
],
"Shop 2": [
(1, "2021/04", "Shop 2", 341227.53),
(4, "2021/04", "Shop 2", 21487.63),
(2, "2021/05", "Shop 2", 315447.24),
(8, "2021/05", "Shop 2", 6548.49),
(9, "2021/06", "Shop 2", 387779.49),
],
}