[英]Pandas resample data by a non-timeseries column (e.g. Price)
Renko Chart Wiki: https://en.wikipedia.org/wiki/Renko_chart
我正在嘗試使用交易報價數據生成磚形圖。 報價數據包含時間戳、價格、交易量。 時間戳采用 unix 毫秒格式。 例如 1649289600174。
Pandas 已經通過df.resample('10Min').agg({'Price': 'ohlc', 'volume': 'sum'})
支持 OHLC 重采樣。 但是,我想根據price重新采樣貿易數據。 不是按時間戳。
Renko 圖表使用固定的磚塊尺寸。 例如,如果價格上漲 10 點或 go 下跌 10 點,則 brick_size 為 10 將生成一塊磚。
一位 pandas 貢獻者告訴我,這可以通過groupby with a binned grouper
binned grouper 來完成。 不過,我不太明白他在說什么。
這就是我的原始數據的樣子。
Timestamp Price Volume
1649289600174 100 100
1649289600176 105 100
1649289600178 110 100
1649289600179 104 100
1649289600181 101 100
1649289600182 100 100
1649289600183 103 100
1649289600184 107 100
1649289600185 102 100
1649289600186 99 100
1649289600188 93 100
1649289600189 90 100
1649289600192 95 100
1649289600193 100 100
1649289600194 105 100
1649289600195 110 100
1649289600196 115 100
1649289600197 120 100
我正在尋找一個看起來像df.resample('10Numeric').agg({'Price': 'ohlc', 'volume': 'sum'})
。 這里10Numeric
表示,brick_size 是 10。如果價格上漲 10 點,或 go 下跌 10 點,那么我想匯總該期間內的數據。
output 應該是這樣的
Timestamp Open High Low Close Volume
1649289600178 100 110 100 110 300
1649289600182 110 110 100 100 300
1649289600189 100 107 90 90 600
1649289600193 90 100 90 100 200
1649289600195 100 110 100 110 200
1649289600197 110 120 110 120 200
我相信 pandas 貢獻者在談論 pd.cut 選項。 然后做groupby。 像這樣的東西。
import pandas as pd
import numpy as np
df = pd.DataFrame({'price': np.random.randint(1, 100, 1000)})
df['bins'] = pd.cut(x=df['price'], bins=[0, 10, 20, 30, 40, 50, 60,
70, 80, 90, 100])
output 看起來像這樣。
price bins
0 92 (90, 100]
1 15 (10, 20]
2 54 (50, 60]
3 55 (50, 60]
4 72 (70, 80]
.. ... ...
95 88 (80, 90]
96 21 (20, 30]
97 91 (90, 100]
98 51 (50, 60]
99 18 (10, 20]
請注意:價格數據不是唯一的。 一年前比特幣的價格應該是 45555 美元。 但今年又是同樣的價格。 如果我使用 100 bin 大小,它將在 (45500, 45600) 中。
groupby 會將 1 年前的數據和當前數據放在同一個箱子中。 我正在尋找跟隨價格變動的解決方案。 例如,收盤價應如下所示45500, 45600, 45700, 45600, 45500, 45400, 45300, 45200, 45100, 45000
有人可以解釋 pandas 貢獻者說groupby with a binned grouper
binned grouper 時的意思嗎?
這是你要找的嗎?
df['bins'] = pd.cut(x=df['Price'], bins=range(df['Price'].min(), df['Price'].max(), 10))
df.groupby('bins').agg({'Price': 'ohlc', 'Volume': 'sum'})
Output:
Price Volume
open high low close Volume
bins
(90, 100] 100 100 93 100 600
(100, 110] 105 110 101 110 900
您可以基於pd.cut
創建一個新列,執行cumsum
,並以此為基礎進行分組。
import pandas as pd
import numpy as np
df = pd.DataFrame(
[
{"Timestamp": 1649289600174, "Price": 100, "Volume": 100},
{"Timestamp": 1649289600176, "Price": 105, "Volume": 100},
{"Timestamp": 1649289600178, "Price": 110, "Volume": 100},
{"Timestamp": 1649289600179, "Price": 104, "Volume": 100},
{"Timestamp": 1649289600181, "Price": 101, "Volume": 100},
{"Timestamp": 1649289600182, "Price": 100, "Volume": 100},
{"Timestamp": 1649289600183, "Price": 103, "Volume": 100},
{"Timestamp": 1649289600184, "Price": 107, "Volume": 100},
{"Timestamp": 1649289600185, "Price": 102, "Volume": 100},
{"Timestamp": 1649289600186, "Price": 99, "Volume": 100},
{"Timestamp": 1649289600188, "Price": 93, "Volume": 100},
{"Timestamp": 1649289600189, "Price": 90, "Volume": 100},
{"Timestamp": 1649289600192, "Price": 95, "Volume": 100},
{"Timestamp": 1649289600193, "Price": 100, "Volume": 100},
{"Timestamp": 1649289600194, "Price": 105, "Volume": 100},
{"Timestamp": 1649289600195, "Price": 110, "Volume": 100},
{"Timestamp": 1649289600196, "Price": 115, "Volume": 100},
{"Timestamp": 1649289600197, "Price": 120, "Volume": 100},
]
)
codes = pd.cut(df["Price"], bins=np.arange(0, 200, 10), right=False).cat.codes
df.groupby((codes != codes.shift(1)).cumsum()).agg(
{"Price": "ohlc", "Volume": "sum", "Timestamp": "min"}
)
這會給你:
Price Volume Timestamp
open high low close Volume Timestamp
1 100 105 100 105 200 1649289600174
2 110 110 110 110 100 1649289600178
3 104 107 100 102 600 1649289600179
4 99 99 90 95 400 1649289600186
5 100 105 100 105 200 1649289600193
6 110 115 110 115 200 1649289600195
7 120 120 120 120 100 1649289600197
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.