更新图表线时出现错误:.str 访问器仅可用于字符串值

0 投票
1 回答
110 浏览
提问于 2025-04-14 17:57

我在使用 .update 方法处理我的线条对象时遇到了困难。我很确定我对 pd.Series 的格式理解是正确的,并且尽量按照文档的说明去做。

终端输出显示:

收到 avg_series_high: 2024-03-05 3693.797625 dtype: float64

然后我收到了以下错误信息:

在 update_chart_lines 中发生错误:只能对字符串值使用 .str 访问器!

我之前从未见过这个错误,使用 pd 时也没有遇到过,网上找到的所有关于这个错误的例子似乎都表明,系列的名称可能没有被自动当作字符串处理?

任何帮助或建议都将非常感谢。

代码示例

async def update_chart_lines(self, avg_line_high, avg_line_low, avg_line_high2, avg_line_low2, queue):
        print("Starting update_chart_lines function")
        avg_data = None

        while True:
            try:
                avg_data = await queue.get()

                if avg_data is not None and 'date' in avg_data:

                    avg_data['date'] = pd.to_datetime(avg_data['date'], unit='ms')
                    # Create a pandas Series for each line
                    avg_series_high_data = pd.Series([avg_data['avg_last_candles_high']], index=[avg_data['date']])
                    avg_series_low_data = pd.Series([avg_data['avg_last_candles_low']], index=[avg_data['date']])
                    avg_series_high2_data = pd.Series([avg_data['avg_last_candles_high2']], index=[avg_data['date']])
                    avg_series_low2_data = pd.Series([avg_data['avg_last_candles_low2']], index=[avg_data['date']])

                    print(f"Received avg_series_high: {avg_series_high_data}")

                    # Update each line with the corresponding pandas Series
                    avg_line_high.update(avg_series_high_data)
                    avg_line_low.update(avg_series_low_data)
                    avg_line_high2.update(avg_series_high2_data)
                    avg_line_low2.update(avg_series_low2_data)
                else:
                    print("No avg candle ticks to process.")
                    continue
            except Exception as e:
                print(f"Error occurred in update_chart_lines: {e}")

这段代码不断生成一个数据框,并将其发送到 update_chart_lines:

async def last_candles_cont(df, n, timeframe, queue):

  timeframe = timeframe

  """ print(f"Calculating average of last {n} candles for {timeframe} timeframe") """

  multipliers = {
    '1d': 1.025,
    '4h': 1.015,
    '1h': 1.01,
    '15m': 1.005,
    '5m': 1.001,
    '1m': 1.00
  }

  while True:
    try:  

      avg_data = None
          
      tick= await queue.get()

      print(f"Received tick: {tick}")

      tick_df = pd.DataFrame(tick, index=[0])

      df = pd.concat([df, tick_df], ignore_index=True)

      """ df['diff'] = df['close'] - df['close'].shift(1)
      print (df['diff'])

      # Calculate the rate of change as a percentage
      df['roc'] = df['diff'] / df['close'].shift(1) * 100
      print (df['roc']) """

      multiplier = multipliers[timeframe]

      df['avg_last_candles_high'] = (df['high']*multiplier).shift(1).rolling(n).mean()
      df['avg_last_candles_low'] = (df['low']/multiplier).shift(1).rolling(n).mean()

      df['avg_last_candles_high2'] = (df['high']*multiplier).rolling(n).mean()
      df['avg_last_candles_low2'] = (df['low']/multiplier).rolling(n).mean()

      avg_data = pd.DataFrame({
              'date': (df['date']),
              'avg_last_candles_high': df['avg_last_candles_high'],
              'avg_last_candles_low': df['avg_last_candles_low'],
              'avg_last_candles_high2': df['avg_last_candles_high2'],
              'avg_last_candles_low2': df['avg_last_candles_low2'],
          }).dropna()
      
      current_candle = avg_data.tail(1).squeeze()
      print(f"Current candle: {current_candle}")
      # Put the current candle into the queue
      await queue.put(current_candle)

      await asyncio.sleep(1)

      """ return avg_data """

    except Exception as e:
      print(f"Error in avg candle function: {e}")
      return pd.DataFrame()  # Return an empty DataFrame in case of error

1 个回答

2

我对lightweight-charts没有经验,但你的问题似乎和你传给.update的数据有关。

问题

你是这样创建pandas系列的:

avg_series_high_data = pd.Series([avg_data['avg_last_candles_high']], index=[avg_data['date']])

这样做实际上是创建了一个以日期为索引,并且每个日期都有对应值的系列。大致像这样:

2024-03-11    1
2024-03-12    2
2024-03-13    3
2024-03-14    4

问题在于lightweight-charts期待的pandas系列格式不同,也就是说,它希望每一行的数据框都有一个系列,包含一个索引是'date',另一个索引是'some_value'……等等。所以应该更像这样:

date      2016-12-28 00:00:00
open                  14.6667
high                    14.92
low                     14.48
close                  14.616
volume             48715005.0

错误信息

你看到的错误是因为lightweight-charts期待datetime在系列的索引中。如果没有,它会假设这些词可能是大写的,并且会调用.str.lower()来处理。

在你传给它的系列中,索引值是datetime类型,所以就会抛出这个错误:

在update_chart_lines中发生错误:只能对字符串值使用.str访问器!

该怎么做

你需要按照上面建议的格式创建pandas系列。我没有你的数据,所以很难给出更具体的建议。因为这是一个线图,我假设每个系列大概会像这样:

date      2016-12-28 00:00:00
open                  14.6667

撰写回答