簡體   English   中英

Pandas 按非時間序列列(例如價格)對數據重新采樣

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM