сложение данных в колонке и агрегация
пытаюсь сгруппировать данные в колонке price, что бы разница была не 0.01 а 0.02 и сгруппированные price положить в кортеж, также в колонке vol суммировать данные по сгруппированным price.Думал реализовать через кумулятивную сумму остатков price поделив их нацело // 0.02, и потом сгруппировать, но разница в price в результате плавает от 0.01 до 0.03.Так же я подумал что проблема в числах флоат,и домножал price на 100 и делил на // 2 что бы получить int в исходных данных, но этот тоже не дало результата Мой код:
price = [str(i / 100) for i in range(20)]
vol = [random.randint(100, 300) for i in range(20)]
price.reverse()
data = ({'vol': vol, 'price': price})
df = (pd.DataFrame(data).astype({'price': 'float'})
.eval('diffs=price.diff().fillna(0).abs().cumsum().round(2)// 0.02')
.groupby('diffs')
.agg(vol=('vol', 'sum'), price=('price', 'min'), tags=('price', tuple)))
print(df)
результат должен быть такой:
vol price tags
295 0.18 (0.19, 0.18)
455 0.16 (0.17, 0.16)
655 0.14 (0.15, 0.14)
284 0.12 (0.13,0.12)
549 0.10 (0.11, 0.10)
770 0.08 (0.09, 0.08)
199 0.06 (0.70,0.06)
552 0.04 (0.05, 0.04)
708 0.02 (0.03, 0.02)
171 0.00 (0.10, 0.00)
p.s в vol сумма должна быть тех цен которые в tags, количество знаков после запятой должно везде быть 2 даже если число к примеру 0.70.И в колонке price шаг цен должен оставаться всегда 0.02 не зависимо от четности количества строк
Ответы (1 шт):
import random
price = reversed([i / 100 for i in range(20)])
vol = [random.randint(100, 300) for i in range(20)]
df = pd.DataFrame({'vol': vol, 'price': price})
df['price00'] = df.price.map("{0:.2f}".format)
df = df.groupby(df.price.mul(100).mod(2).astype(int).cumsum()).agg(vol=('vol', 'sum'), price=('price', 'min'), tags=('price00', tuple))
print(df)
vol price tags
price
1 552 0.18 (0.19, 0.18)
2 364 0.16 (0.17, 0.16)
3 434 0.14 (0.15, 0.14)
4 472 0.12 (0.13, 0.12)
5 377 0.10 (0.11, 0.10)
6 333 0.08 (0.09, 0.08)
7 314 0.06 (0.07, 0.06)
8 405 0.04 (0.05, 0.04)
9 430 0.02 (0.03, 0.02)
10 367 0.00 (0.01, 0.00)
Если преобразования производить в целых и только в конце поделить на 100 и отформатировать
import random
price = reversed([i for i in range(50)])
vol = [random.randint(100, 300) for i in range(50)]
df = pd.DataFrame({'vol': vol, 'price': price})
df['price00'] = df.price.div(100).map("{0:.2f}".format)
df = df.groupby(df.price.mod(2).astype(int).cumsum()).agg(vol=('vol', 'sum'), price=('price', 'min'), tags=('price00', tuple))
df['price'] = df.price.div(100).map("{0:.2f}".format)
print(df)