The stock prices for the given dates are provided in the question table. Add a new column, Group, starting from 1, and added by 1, whenever the stock price falls below the historical minimum price observed up to that date. Example:On 4/1/2024, the stock price is 43, which is lower than the historical minimum price of 47. Therefore, the group number will be updated to 2.
📌 Challenge Details and Links
Challenge Number: 168
Challenge Difficulty: ⭐
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Custom Grouping! Part 14 with Power Query
Power Query solution 1 for Custom Grouping! Part 14, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
_ = Table.Group(Source, "Stock price", {"R", Table.ToRecords}, 0, (b, n) => Byte.From(b > n)),
S = Table.FromRecords(
List.TransformMany([R], each _, (i, o) => o & [Group = List.PositionOf([R], i) + 1])
)
in
S
Power Query solution 2 for Custom Grouping! Part 14, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
_ = Table.Group(
Source,
{"Date", "Stock price"},
{"R", Table.ToRecords},
0,
(b, n) =>
let
p = each Table.PositionOf(Source, _),
s = each [Stock price]
in
Byte.From(s(n) < List.Min(List.Range(s(Source), p(b), p(n) - p(b)), s(n)))
),
S = Table.FromRecords(
List.TransformMany([R], each _, (i, o) => o & [Group = List.PositionOf([R], i) + 1])
)
in
S
Power Query solution 3 for Custom Grouping! Part 14, proposed by Luan Rodrigues:
let
Fonte = Table.Group(
Tabela1,
{"Stock price"},
{{"tab", each _}},
0,
(a, b) => Number.From(a[Stock price] > b[Stock price])
),
Ind = Table.AddIndexColumn(Fonte, "Group", 1)[[tab], [Group]],
res = Table.ExpandTableColumn(Ind, "tab", {"Date", "Stock price"})
in
res
Power Query solution 4 for Custom Grouping! Part 14, proposed by Ramiro Ayala Chávez:
let
S = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
a = Table.Group(S,"Stock price",{"G", each _},0,(x,y)=>Number.From(x>y)),
b = Table.AddIndexColumn(a,"Group",1)[[G],[Group]],
Sol = Table.ExpandTableColumn(b,"G",{"Date","Stock price"})
in
Sol
Power Query solution 5 for Custom Grouping! Part 14, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Index = Table.AddIndexColumn(Source, "Idx", 0, 1, Int64.Type),
Grp = Table.Group(
Index,
{"Idx", "Stock price"},
{{"A", each _}},
0,
(a, b) => Number.From(b[Stock price] < List.Min(List.FirstN(Index[Stock price], b[Idx])))
)[[A]],
Group = Table.AddIndexColumn(Grp, "Group", 1),
Sol = Table.ExpandTableColumn(Group, "A", Table.ColumnNames(Source))
in
Sol
Power Query solution 6 for Custom Grouping! Part 14, proposed by Kris Jaganah:
let
A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
B = A[Stock price],
C = List.Generate(
() => [a = 0, b = B{0}, c = 1],
each [a] < List.Count(B),
each [a = [a] + 1, b = List.Min(List.FirstN(B, a + 1)), c = if b = [b] then [c] else [c] + 1],
each [c]
),
D = Table.FromColumns({A[Date], C}, Table.ColumnNames(A))
in
D
Power Query solution 7 for Custom Grouping! Part 14, proposed by Abdallah Ally:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Generate = List.Generate(
() => [Row = 0, Cur = Source[Stock price]{0}, Min = Cur, Gr = 1],
each [Row] < Table.RowCount(Source),
each [
Row = [Row] + 1,
Cur = Source[Stock price]{Row},
Min = if Cur < [Min] then Cur else [Min],
Gr = [Gr] + Byte.From(Cur < [Min])
],
each [Gr]
),
ColNames = Table.ColumnNames(Source) & {"Group"},
FromCols = Table.FromColumns(Table.ToColumns(Source) & {Generate}, ColNames),
Result = Table.TransformColumnTypes(FromCols, {"Date", type date})
in
Result
Power Query solution 8 for Custom Grouping! Part 14, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
A = Table.AddIndexColumn(S, "I", 1, 1),
B = Table.AddColumn(A, "L", each List.Min(List.FirstN(A[Stock price], [I]))),
C = Table.RemoveColumns(B, {"I"}),
D = Table.Group(C, {"L"}, {{"T", each _}}),
E = Table.AddIndexColumn(D, "Group", 1, 1),
F = Table.AddColumn(
E,
"T2",
each Table.FromColumns(
{[T][Date], [T][#"Stock price"], List.Repeat({[Group]}, Table.RowCount([T]))},
{"Date", "Stock Price", "Group"}
)
),
G = Table.Combine(F[T2])
in
G
Power Query solution 9 for Custom Grouping! Part 14, proposed by Seokho MOON:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Group = Table.Group(Source, "Stock price", {"All", each _}, 0, (x, y) => Number.From(x > y)),
AddIndex = Table.AddIndexColumn(Group, "Group", 1, 1)[[All], [Group]],
Expand = Table.ExpandTableColumn(AddIndex, "All", {"Date", "Stock price"})
in
Expand
Power Query solution 10 for Custom Grouping! Part 14, proposed by Alexandre Garcia:
let
H = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
P = {"Date", "Stock price"},
L = Table.Group(H, P, {"x", (x)=> x }, 0,(x,y)=> Byte.From(x[Stock price] > y[Stock price])),
C = Table.ExpandTableColumn(Table.RemoveColumns(Table.AddIndexColumn(L, "Group", 1),P),"x",P)
in C
Power Query solution 11 for Custom Grouping! Part 14, proposed by Vida Vaitkunaite:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Custom = Table.AddColumn(Source, "Custom", each let
a = Table.First(Source)[Stock price],
b = if a - [Stock price]>=0 then 1*[Stock price] else null
in b),
FillDown = Table.FillDown(Custom,{"Custom"}),
Groups = Table.Group(FillDown, {"Custom"}, {{"All", each _, type table}}),
Index = Table.RemoveColumns(Table.AddIndexColumn(Groups, "Group", 1, 1), "Custom"),
Final = Table.ExpandTableColumn(Index, "All", {"Date", "Stock price"}, {"Date", "Stock price"})
in
Final
Solving the challenge of Custom Grouping! Part 14 with Excel
Excel solution 1 for Custom Grouping! Part 14, proposed by Oscar Mendez Roca Farell:
=LET(
s,
SCAN(
,
C3:C26,
MIN
),
HSTACK(
B3:C26,
XMATCH(
s,
UNIQUE(
s
)
)
)
)
Excel solution 2 for Custom Grouping! Part 14, proposed by Julian Poeltl:
=LET(
M,
MAP(
C3:C26,
LAMBDA(
A,
MIN(
C3:A
)
)
),
XMATCH(
M,
UNIQUE(
M
)
)
)
Excel solution 3 for Custom Grouping! Part 14, proposed by Kris Jaganah:
=LET(
a,
SCAN(
,
C3:C26,
MIN
),
XMATCH(
a,
UNIQUE(
a
)
)
)
Excel solution 4 for Custom Grouping! Part 14, proposed by Sunny Baggu:
=LET( _a,
MAP( C3:C26, LAMBDA(
a,
MIN(
C3:a
)
) ), HSTACK( B3:C26, XMATCH(
_a,
UNIQUE(
_a
)
) ))
Excel solution 5 for Custom Grouping! Part 14, proposed by Sunny Baggu:
=LET( _s,
SEQUENCE(
ROWS(
B3:B26
)
), _m,
MAP( _s, LAMBDA(
a,
MIN(
TAKE(
C3:C26,
a
)
)
) ), HSTACK(
B3:C26,
XMATCH(
_m,
UNIQUE(
_m
)
)
))
Excel solution 6 for Custom Grouping! Part 14, proposed by Ankur Sharma:
=SCAN(0,
SEQUENCE(
COUNT(
H3:H26
)
),
LAMBDA(i,
a,LET(s,
CHOOSEROWS(
H3:H26,
a
),m,
MIN(
TAKE(
H3:H26,
a
)
),i + (s <= m))))
Excel solution 7 for Custom Grouping! Part 14, proposed by Asheesh Pahwa:
=LET(
t,
TAKE(
C3:C26,
1
),
v,
VSTACK(
TRUE,
DROP(
t>C3:C26,
1
)
), s,
SCAN(
0,
--v*C3:C26,
LAMBDA(
x,
y,
IF(
y,
y,
x
)
)
),
XMATCH(
s,
UNIQUE(
s
)
)
)
Excel solution 8 for Custom Grouping! Part 14, proposed by Asheesh Pahwa:
=LET(
s,
SCAN(
0,
C3:C26,
LAMBDA(
x,
y,
MIN(
C3:y
)
)
),
XMATCH(
s,
UNIQUE(
s
)
)
)
Excel solution 9 for Custom Grouping! Part 14, proposed by Liuxuan Fan:
=IF(
ISNUMBER(
B2
)*1,
IF(
B3
Excel solution 10 for Custom Grouping! Part 14, proposed by Md. Zohurul Islam:
=LET( a,
B3:C26, b,
C3:C26, hdr,
HSTACK(
B2:C2,
"Group"
), u,
SCAN(
C3,
b,
LAMBDA(
x,
y,
MIN(
x,
y
)
)
), v,
VSTACK(
1,
ABS(
DROP(
u,
1
)=DROP(
u,
-1
)
)
), w,
SCAN(
0,
v,
LAMBDA(
x,
y,
IF(
y=0,
x+1,
x
)
)
)+1, z,
VSTACK(
hdr,
HSTACK(
a,
w
)
), z
)
Excel solution 11 for Custom Grouping! Part 14, proposed by Nicolas Micot:
=LET(
_cumMin;
SCAN(
-1;
H3:H26;
LAMBDA(
l_min;
l_valeur;
SI(
OU(
l_min=-1;
l_valeurINDEX(
_cumMin;
l_index-1
);
l_valeurInit+1;
l_valeurInit
)
)
)
)
)
Excel solution 12 for Custom Grouping! Part 14, proposed by Nikola Z Grujicic - Nikola Ž Grujičić:
=LET(
a,
SCAN(
1000,
C3:C26,
LAMBDA(
x,
y,
IF(
y
Excel solution 13 for Custom Grouping! Part 14, proposed by Peter Bartholomew:
= LET( currentMin,
SCAN(
,
price,
MIN
), previousMin,
VSTACK(
"x",
DROP(
currentMin,
-1
)
), change,
currentMin<>previousMin, SCAN(
,
N(
change
),
SUM
))
Excel solution 14 for Custom Grouping! Part 14, proposed by Pieter de B.:
=LET(
r,
REDUCE(
,
C3:C26,
LAMBDA(
a,
b,
VSTACK(
a,
IF(
b
Excel solution 15 for Custom Grouping! Part 14, proposed by Rick Rothstein:
=SCAN(0,
C3:C26,
LAMBDA(a,
x,
a+(x<=MIN(
C3:x
))))
Solving the challenge of Custom Grouping! Part 14 with Python
Python solution 1 for Custom Grouping! Part 14, proposed by Konrad Gryczan, PhD:
import pandas as pd
path = "CH-168 Custom Grouping.xlsx"
input = pd.read_excel(path, usecols="B:C", skiprows=1, nrows=25)
test = pd.read_excel(path, usecols="G:I", skiprows=1, nrows=25).rename(columns=lambda x: x.split('.')[0])
input['Group'] = ((input['Stock price'].cummin() != input['Stock price'].cummin().shift().fillna(input['Stock price'].cummin().iloc[0])).cumsum() + 1)
print(all(input == test)) # True
Python solution 2 for Custom Grouping! Part 14, proposed by Luan Rodrigues:
import pandas as pd
file = "CH-168 Custom Grouping.xlsx"
df = pd.read_excel(file,usecols="B:C",skiprows=1)
df['Group'] = df['Stock price'].cummin()
group_dict = {group: idx+1 for idx, group in enumerate(df['Group'].unique())}
df['Group'] = df['Group'].map(group_dict)
print(df)
Python solution 3 for Custom Grouping! Part 14, proposed by Abdallah Ally:
import pandas as pd
# Load the Excel file
file_path = CH-168 Custom Grouping.xlsx'
df = pd.read_excel(file_path, usecols='B:C', skiprows=1)
# Perform data manipulation
group_values = []
minimum = df.iat[0, 1]
group = 1
for price in df['Stock price']:
if price < minimum:
minimum = price
group += 1
group_values.append(group)
df['Group'] = group_values
# Display the final results
df
Solving the challenge of Custom Grouping! Part 14 with Python in Excel
Python in Excel solution 1 for Custom Grouping! Part 14, proposed by Abdallah Ally:
_xDCB9_Office script solution ✍
hashtag
#Python
hashtag
#R
hashtag
#SQL
hashtag
#Excel
hashtag
#VBA
hashtag
#OfficeScript
hashtag
#PowerBI
hashtag
#PowerQuery
function main(workbook: ExcelScript.Workbook) {
// Get the active worksheet and initialize values.
const curSheet = workbook.getActiveWorksheet();
const resCell = curSheet.getRange('K2');
const curRegion = curSheet.getRange('B2').getSurroundingRegion();
const copyRange = curRegion.getOffsetRange(1, 0).getResizedRange(-1, 0);
const colCount = copyRange.getColumnCount();
const rowCount = copyRange.getRowCount();
// Paste values and add a heading
resCell.copyFrom(copyRange, ExcelScript.RangeCopyType.values);
resCell.getOffsetRange(0, colCount).setValue('Group')
let minimum = resCell.getOffsetRange(1, colCount - 1).getValue();
let groupValue = 1;
for (let cRow = 1; cRow < rowCount; cRow++) {
const cRange = resCell.getOffsetRange(cRow, colCount - 1);
const cValue = cRange.getValue() as number;
if (minimum > cValue) {
minimum = cValue;
groupValue++
}
cRange.getOffsetRange(0, 1).setValue(groupValue);
}
}
Python in Excel solution 2 for Custom Grouping! Part 14, proposed by Alejandro Campos:
df = xl("B2:C26", headers=True)
df['Group'] = 1
min_price = df.loc[0, 'Stock price']
for i in range(1, len(df)):
if df.loc[i, 'Stock price'] < min_price:
min_price = df.loc[i, 'Stock price']
df.loc[i:, 'Group'] = df.loc[i, 'Group'] + 1
df
Solving the challenge of Custom Grouping! Part 14 with R
R solution 1 for Custom Grouping! Part 14, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "files/CH-168 Custom Grouping.xlsx"
input = read_excel(path, range = "B2:C26")
test = read_excel(path, range = "G2:I26")
result = input %>%
mutate(group = cumsum(cummin(`Stock price`) != lag(cummin(`Stock price`), default = first(cummin(`Stock price`)))) + 1)
all.equal(result, test, check.attributes = FALSE)
#> [1] TRUE
Solving the challenge of Custom Grouping! Part 14 with Google Sheets
Google Sheets solution 1 for Custom Grouping! Part 14, proposed by Peter Krkos:
PowerQuery solution:
https://docs.google.com/spreadsheets/d/1zR5IZLz8OT76vhaPEHfsPrw8-RDKnLyyqS49IJjdhFk/edit?pli=1&gid=933552922#gid=933552922
