【问题标题】:Websocket Json Data to DataFrameWebsocket Json 数据到 DataFrame
【发布时间】:2022-08-02 16:23:59
【问题描述】:

我正在学习如何在金融领域使用 API 和 Web 套接字。 我对这段代码的目标是访问数据并创建一个只有列(索引、询问、出价和报价)的 DataFrame 我尝试将值附加到 DataFrame 但每次收到消息时它都会创建一个新的 DataFrame 类似于df = new_df.loc[0] = data

当前代码的输出

0    {\'ask\': 20150.93, \'bid\': 20144.93, \'epoch\': 16...
Name: tick, dtype: object

加载json后的字典

{\'echo_req\': {\'ticks\': \'R_100\'}, \'msg_type\': \'tick\', \'subscription\': {\'id\': \'248a0656-44e9-91da-5e06-10712edf2cdf\'}, \'tick\': {\'ask\': 20150.19, \'bid\': 20144.19, \'epoch\': 1658228500, \'id\': \'248a0656-44e9-91da-5e06-10712edf2cdf\', \'pip_size\': 2, \'quote\': 20147.19, \'symbol\': \'R_100\'}}

期望的输出

index、ask、bid、quote 作为列

每次我们收到新消息或打勾时,将值作为行附加。

import websocket
import json
import pandas as pd
    
app_id = \'*****\'  # Replace with your app_id.
    
def on_open(ws):
    json_data = json.dumps({\"ticks\": \"R_100\"})
    ws.send(json_data)

def on_message(ws, message):    
    global df
    data = json.loads(message)
    row = {
        \'ask\': [data[\'tick\'][\'ask\']],  # it has to be list
        \'bid\': [data[\'tick\'][\'bid\']],  # it has to be list
        \'epoch\': [data[\'tick\'][\'epoch\']],  # it has to be list
    }    
\"\"\"
if __name__ == \'__main__\':
    df = pd.DataFrame()
    on_message(None, json.dumps(data))
    on_message(None, json.dumps(data))
    print(df.to_string())
\"\"\"
if __name__ == \"__main__\":
    apiUrl = \"wss:///websockets/v3?app_id=\" + app_id
    ws = websocket.WebSocketApp(apiUrl, on_message=on_message, on_open=on_open)
    ws.run_forever()
    
  • 首先,您可以编辑问题并使用特殊功能来格式化代码(即 Ctrl+K),因为此时它对我们毫无用处。
  • 也许首先创建列表并使用.append(),然后将此列表转换为数据框。或者您应该使用特殊方法来附加数据 - .join().append().merge().concatenate()。您不能使用= 附加数据。您应该在开始时创建空数据框作为全局变量。

标签: python pandas websocket


【解决方案1】:

您应该在开始时创建空的DataFrame 作为全局变量,然后使用.append() 将新行添加到此数据框。

最小的工作示例(但没有 API)

example_data = {
    'echo_req': {'ticks': 'R_100'},
    'msg_type': 'tick',
    'subscription': {'id': '248a0656-44e9-91da-5e06-10712edf2cdf'},
    'tick': {
        'ask': 20150.19,
        'bid': 20144.19,
        'epoch': 1658228500,
        'id': '248a0656-44e9-91da-5e06-10712edf2cdf',
        'pip_size': 2,
        'quote': 20147.19,
        'symbol': 'R_100'
    }
}

import json
import pandas as pd

def on_message(ws, message):
    global df

    data = json.loads(message)
    
    row = {
        'ask': data['tick']['ask'],
        'bid': data['tick']['bid'],
        'epoch': data['tick']['epoch'],
    }
    
    df = df.append(row, ignore_index=True)
    
if __name__ == '__main__':
    df = pd.DataFrame()

    on_message(None, json.dumps(example_data))
    on_message(None, json.dumps(example_data))
    
    print(df.to_string())

结果:

        ask       bid         epoch
0  20150.19  20144.19  1.658228e+09
1  20150.19  20144.19  1.658228e+09

编辑:

因为.append() 已被弃用并且pandas 建议使用concat()

example_data = {
    'echo_req': {'ticks': 'R_100'},
    'msg_type': 'tick',
    'subscription': {'id': '248a0656-44e9-91da-5e06-10712edf2cdf'},
    'tick': {
        'ask': 20150.19,
        'bid': 20144.19,
        'epoch': 1658228500,
        'id': '248a0656-44e9-91da-5e06-10712edf2cdf',
        'pip_size': 2,
        'quote': 20147.19,
        'symbol': 'R_100'
    }
}

import json
import pandas as pd

def on_message(ws, message):
    global df

    data = json.loads(message)
    
    row = {
        'ask': [ data['tick']['ask'] ],      # it has to be list
        'bid': [ data['tick']['bid'] ],      # it has to be list 
        'epoch': [ data['tick']['epoch'] ],  # it has to be list
    }

    new_df = pd.DataFrame(row)
    df = pd.concat([df, new_df], ignore_index=True)
    
if __name__ == '__main__':
    df = pd.DataFrame()

    on_message(None, json.dumps(example_data))
    on_message(None, json.dumps(example_data))
    
    print(df.to_string())

带有 websocket 的版本 - 但我无法测试它

编辑:最初的问题是使用ws.binaryws.com,但作者将其更改为websocket,但这对其他用户可能无用 - 所以我将在我的代码中保留原始ws.binaryws.com

import websocket
import json
import pandas as pd
    
app_id = '*****'  # Replace with your app_id.
    
def on_open(ws):
    json_data = json.dumps({"ticks": "R_100"})
    ws.send(json_data)

def on_message(ws, message):    
    global df
    data = json.loads(message)
    row = {
        'ask':   [data['tick']['ask']],    # it has to be list
        'bid':   [data['tick']['bid']],    # it has to be list
        'epoch': [data['tick']['epoch']],  # it has to be list
    }
    new_df = pd.DataFrame(row)
    df = pd.concat([df, new_df], ignore_index=True)

if __name__ == "__main__":
    df = pd.DataFrame()
    apiUrl = "wss://ws.binaryws.com/websockets/v3?app_id=" + app_id
    ws = websocket.WebSocketApp(apiUrl, on_message=on_message, on_open=on_open)
    ws.run_forever()

【讨论】:

  • 你的代码是对的。您能协助将您的代码集成到 WebSocket 中吗?我已经编辑了代码。
  • 你在新的on_message 中忘记了new_df = pd.DataFrame(row) df = df.append(row, ignore_index=True)。你必须在if __name__ == "__main__": 中创建df = pd.DataFrame()
  • 我使用 websocket 添加了代码,但我无法对其进行测试 - 我在此门户上没有帐户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
  • 2017-12-01
  • 2018-10-16
  • 2019-08-06
  • 2019-11-30
  • 1970-01-01
相关资源
最近更新 更多