最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python 3.x - Numba namedtuple & ListType weird Question - Stack Overflow

programmeradmin3浏览0评论

I get a weird problem against numba with namedtuple & ListType.

I defined 2 namedtuple as below. These 2 are similar. But one works well other one not work.

import numba as nb
from numba.experimental import jitclass
from collections import namedtuple


TransNote = namedtuple('TransNote',
                       ['sym_id', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost',
                        'sell_date', 'sell_price', 'sell_income'])
TransNoteType = nb.types.NamedTuple([nb.int64, nb.int64, nb.float64, nb.float64, nb.float64,
                                     nb.int64, nb.float64, nb.float64],
                                    TransNote)

StockRec = namedtuple('StockRec', ['sym_id', 'price', 'sell_date', 'sell_price', 'sell_income', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost'])
StockRecType = nb.types.NamedTuple([nb.int64, nb.float64, nb.int64, nb.float64, nb.float64, nb.int64, nb.float64, nb.int64, nb.float64], StockRec)

About 2 namedtuple are similar but StockRec works well. And TransNote does not work.

Below is the code to operate these 2 namedtuple:

@jitclass()
class TNLite:
    tn_list: nb.types.ListType(TransNoteType)
    stock_ls: nb.types.ListType(StockRecType)

    def __init__(self):
        self.tn_list = nb.typed.List.empty_list(TransNoteType)
        self.stock_ls = nb.typed.List.empty_list(StockRecType)

    def append_tn(self, sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income):
        item = TransNote(sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income)
        self.tn_list.append(item)  # <==== weird line

    def append_rec(self, symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost):
        item = StockRec(symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost)
        self.stock_ls.append(item)

    def get_rec(self):
        return self.stock_ls

If the highlight line <==== is commented out. It works. Otherwise it will break.

Below is the unit-test code:

if __name__ == '__main__':
    tn_lite = TNLite()

    tn_lite.append_tn(10, 20_000, 11.23, 100, 1123.0, 21_000, 11.11, 1111.0)
    tn_lite.append_rec(101, 11.23, 21_000, 11.11, 1111.0, 20240107, 11.15, 100, 115.67)

    stock_list = tn_lite.get_rec()
    print(stock_list)

The error raised like below:

  File "/Users/joseph/anaconda3/envs/xbx-py11-2/lib/python3.11/site-packages/numba/core/lowering.py", line 830, in _cast_var
    return self.context.cast(self.builder, val, varty, ty)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/joseph/anaconda3/envs/xbx-py11-2/lib/python3.11/site-packages/numba/core/base.py", line 702, in cast
    return impl(self, builder, fromty, toty, val)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/joseph/anaconda3/envs/xbx-py11-2/lib/python3.11/site-packages/numba/cpython/tupleobj.py", line 382, in tuple_to_tuple
    raise NotImplementedError
NotImplementedError

To help you quick re-produce this issue. I put the full *.py file at below:

import numba as nb
from numba.experimental import jitclass
from collections import namedtuple


TransNote = namedtuple('TransNote',
                       ['sym_id', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost',
                        'sell_date', 'sell_price', 'sell_income'])
TransNoteType = nb.types.NamedTuple([nb.int64, nb.int64, nb.float64, nb.float64, nb.float64,
                                     nb.int64, nb.float64, nb.float64],
                                    TransNote)

StockRec = namedtuple('StockRec', ['sym_id', 'price', 'sell_date', 'sell_price', 'sell_income', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost'])
StockRecType = nb.types.NamedTuple([nb.int64, nb.float64, nb.int64, nb.float64, nb.float64, nb.int64, nb.float64, nb.int64, nb.float64], StockRec)


@jitclass()
class TNLite:
    tn_list: nb.types.ListType(TransNoteType)
    stock_ls: nb.types.ListType(StockRecType)

    def __init__(self):
        self.tn_list = nb.typed.List.empty_list(TransNoteType)
        self.stock_ls = nb.typed.List.empty_list(StockRecType)

    def append_tn(self, sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income):
        item = TransNote(sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income)
        self.tn_list.append(item)  # <==== weird line

    def append_rec(self, symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost):
        item = StockRec(symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost)
        self.stock_ls.append(item)

    def get_rec(self):
        return self.stock_ls


if __name__ == '__main__':
    tn_lite = TNLite()

    tn_lite.append_tn(10, 20_000, 11.23, 100, 1123.0, 21_000, 11.11, 1111.0)
    tn_lite.append_rec(101, 11.23, 21_000, 11.11, 1111.0, 20240107, 11.15, 100, 115.67)

    stock_list = tn_lite.get_rec()
    print(stock_list)

I get a weird problem against numba with namedtuple & ListType.

I defined 2 namedtuple as below. These 2 are similar. But one works well other one not work.

import numba as nb
from numba.experimental import jitclass
from collections import namedtuple


TransNote = namedtuple('TransNote',
                       ['sym_id', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost',
                        'sell_date', 'sell_price', 'sell_income'])
TransNoteType = nb.types.NamedTuple([nb.int64, nb.int64, nb.float64, nb.float64, nb.float64,
                                     nb.int64, nb.float64, nb.float64],
                                    TransNote)

StockRec = namedtuple('StockRec', ['sym_id', 'price', 'sell_date', 'sell_price', 'sell_income', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost'])
StockRecType = nb.types.NamedTuple([nb.int64, nb.float64, nb.int64, nb.float64, nb.float64, nb.int64, nb.float64, nb.int64, nb.float64], StockRec)

About 2 namedtuple are similar but StockRec works well. And TransNote does not work.

Below is the code to operate these 2 namedtuple:

@jitclass()
class TNLite:
    tn_list: nb.types.ListType(TransNoteType)
    stock_ls: nb.types.ListType(StockRecType)

    def __init__(self):
        self.tn_list = nb.typed.List.empty_list(TransNoteType)
        self.stock_ls = nb.typed.List.empty_list(StockRecType)

    def append_tn(self, sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income):
        item = TransNote(sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income)
        self.tn_list.append(item)  # <==== weird line

    def append_rec(self, symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost):
        item = StockRec(symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost)
        self.stock_ls.append(item)

    def get_rec(self):
        return self.stock_ls

If the highlight line <==== is commented out. It works. Otherwise it will break.

Below is the unit-test code:

if __name__ == '__main__':
    tn_lite = TNLite()

    tn_lite.append_tn(10, 20_000, 11.23, 100, 1123.0, 21_000, 11.11, 1111.0)
    tn_lite.append_rec(101, 11.23, 21_000, 11.11, 1111.0, 20240107, 11.15, 100, 115.67)

    stock_list = tn_lite.get_rec()
    print(stock_list)

The error raised like below:

  File "/Users/joseph/anaconda3/envs/xbx-py11-2/lib/python3.11/site-packages/numba/core/lowering.py", line 830, in _cast_var
    return self.context.cast(self.builder, val, varty, ty)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/joseph/anaconda3/envs/xbx-py11-2/lib/python3.11/site-packages/numba/core/base.py", line 702, in cast
    return impl(self, builder, fromty, toty, val)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/joseph/anaconda3/envs/xbx-py11-2/lib/python3.11/site-packages/numba/cpython/tupleobj.py", line 382, in tuple_to_tuple
    raise NotImplementedError
NotImplementedError

To help you quick re-produce this issue. I put the full *.py file at below:

import numba as nb
from numba.experimental import jitclass
from collections import namedtuple


TransNote = namedtuple('TransNote',
                       ['sym_id', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost',
                        'sell_date', 'sell_price', 'sell_income'])
TransNoteType = nb.types.NamedTuple([nb.int64, nb.int64, nb.float64, nb.float64, nb.float64,
                                     nb.int64, nb.float64, nb.float64],
                                    TransNote)

StockRec = namedtuple('StockRec', ['sym_id', 'price', 'sell_date', 'sell_price', 'sell_income', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost'])
StockRecType = nb.types.NamedTuple([nb.int64, nb.float64, nb.int64, nb.float64, nb.float64, nb.int64, nb.float64, nb.int64, nb.float64], StockRec)


@jitclass()
class TNLite:
    tn_list: nb.types.ListType(TransNoteType)
    stock_ls: nb.types.ListType(StockRecType)

    def __init__(self):
        self.tn_list = nb.typed.List.empty_list(TransNoteType)
        self.stock_ls = nb.typed.List.empty_list(StockRecType)

    def append_tn(self, sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income):
        item = TransNote(sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income)
        self.tn_list.append(item)  # <==== weird line

    def append_rec(self, symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost):
        item = StockRec(symbol, price, s_date, s_price, s_income, b_date, b_price, b_pos, b_cost)
        self.stock_ls.append(item)

    def get_rec(self):
        return self.stock_ls


if __name__ == '__main__':
    tn_lite = TNLite()

    tn_lite.append_tn(10, 20_000, 11.23, 100, 1123.0, 21_000, 11.11, 1111.0)
    tn_lite.append_rec(101, 11.23, 21_000, 11.11, 1111.0, 20240107, 11.15, 100, 115.67)

    stock_list = tn_lite.get_rec()
    print(stock_list)

Share Improve this question asked Feb 15 at 6:05 Joseph CenJoseph Cen 1091 silver badge8 bronze badges 2
  • If I use 100.0 instead of 100 in the append_tn call, I don't get an error. Looks like Numba isn't converting the int to a float, but I don't know why. – user2357112 Commented Feb 15 at 6:14
  • Thanks, I guess you are correct. Let me correct my code and do a little more try. – Joseph Cen Commented Feb 15 at 14:52
Add a comment  | 

1 Answer 1

Reset to default 0

Thanks for 'user2357112'.

You are corrected. It works now.

The argument and Numba signature must be matched exactly.

# type define
TransNote = namedtuple('TransNote',
                       ['sym_id', 'buy_date', 'buy_price', 'buy_pos', 'buy_cost',
                        'sell_date', 'sell_price', 'sell_income'])
TransNoteType = nb.types.NamedTuple([nb.int64, nb.int64, nb.float64, nb.float64, nb.float64,
                                     nb.int64, nb.float64, nb.float64],
                                    TransNote)

# function definition
    def append_tn(self, sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income):
        item = TransNote(sym_id, buy_date, buy_price, buy_pos, buy_costs, sell_date, sell_price, sell_income)
        self.tn_list.append(item)

# Call function
tn_lite.append_tn(10, 20_000, 11.23, 100, 1123.0, 21_000, 11.11, 1111.0)
#                                     ^

But for numba, it is a little difficult for debugging these exception. For namedtuple and numba List, we can also refer [github]NamedTuple type and List #6355.

发布评论

评论列表(0)

  1. 暂无评论