You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Jupyter Notebook中传参调用函数时触发IndexError问题求助

商品推荐系统数据传入对比模块报错问题

我正在开发一款商品推荐系统,在将数据传入对比模块时遇到困难。

数据情况

我的数据为电子表格格式,包含PN(产品编号)、Item(商品名称)、Description(描述)、Keywords(关键词)、Price(价格)字段,还有用于相似度计算的keywords_bin字段。

代码实现

from scipy import spatial
def Similarity(Item1, Item2):
    a = products.iloc[Item1]
    b = products.iloc[Item2]
    
    keywordsA = a['keywords_bin']
    keywordsB = b['keywords_bin']
    
    kywdDistance = spatial.distance.cosine(keywordsA, keywordsB)

    return kywdDistance

def get_recommendations(name):
    
    new_product = products[products['Item'].str.contains(name)].iloc[0].to_frame().T
    print('Selected Item: ',new_product.PN.values[0],' - ',new_product.Item.values[0],' - ',
        new_product.Description.values[0],' - ',new_product.Keywords.values[0],' - ',
          new_product.Price.values[0])
    def getNeighbors(baseItem, K):
        distances = []
    
        for index, row in products.iterrows():
            if row['PN'] != baseItem['PN'].values[0]:
                dist = Similarity(baseItem['PN'].values[0], row['PN'])
                distances.append((row['PN'], dist))
    
        distances.sort(key=operator.itemgetter(1))
        neighbors = []
    
        for x in range(K):
            neighbors.append(distances[x])
        return neighbors
    
    K = 10
    neighbors = getNeighbors(new_product, K)
    print('\nRecommended Products: \n')
    for neighbor in neighbors:
        print( products.iloc[neighbor[0]][0]+" | Keywords: "+ 
              str(products.iloc[neighbor[0]][1]).strip('[]').replace(' ',''))
    
    print('\n')

我设置了下拉列表供用户选择商品,本该基于关键词相似度生成推荐结果,却触发了以下错误:

Cell In[237], line 7
         1 button = widgets.Button(
         2     description='Get Recommendations',
         3     disabled=False,
         4     button_style='', # 'success', 'info', 'warning', 'danger' or ''
         5     tooltip='Get Recommendations')
         6 display(button)
   ----> 7 button.on_click(get_recommendations(name))

   Cell In[235], line 23, in get_recommendations(name)
        20     return neighbors
        22 K = 10
   ---> 23 neighbors = getNeighbors(new_product, K)
        24 print('\nRecommended Products: \n')
        25 for neighbor in neighbors:

   Cell In[235], line 12, in get_recommendations.<locals>.getNeighbors(baseItem, K)
        10     print(row.PN, ' ', baseItem.PN)
        11     if row['PN'] != baseItem['PN'].values[0]:
   ---> 12         dist = Similarity(baseItem['PN'].values[0], row['PN'])
        13         distances.append((row['PN'], dist))
        15 distances.sort(key=operator.itemgetter(1))

   Cell In[26], line 4, in Similarity(Item1, Item2)
         2 def Similarity(Item1, Item2):
         3     a = products.iloc[Item1]
   ---> 4     b = products.iloc[Item2]
         6     keywordsA = a['keywords_bin']
         7     keywordsB = b['keywords_bin']

   File c:\program files\python38\lib\site-packages\pandas\core\indexing.py:1103, in _LocationIndexer.__getitem__(self, key)
      1100 axis = self.axis or 0
      1102 maybe_callable = com.apply_if_callable(key, self.obj)
   -> 1103 return self._getitem_axis(maybe_callable, axis=axis)

   File c:\program files\python38\lib\site-packages\pandas\core\indexing.py:1656, in _iLocIndexer._getitem_axis(self, key, axis)
      1653     raise TypeError("Cannot index by location index with a non-integer key")
      1655 # validate the location
   -> 1656 self._validate_integer(key, axis)
      1658 return self.obj._ixs(key, axis=axis)

   File c:\program files\python38\lib\site-packages\pandas\core\indexing.py:1589, in _iLocIndexer._validate_integer(self, key, axis)
      1587 len_axis = len(self.obj._get_axis(axis))
      1588 if key >= len_axis or key < -len_axis:
   -> 1589     raise IndexError("single positional indexer is out-of-bounds")

IndexError: single positional indexer is out-of-bounds

错误原因及修复方案

核心问题

  1. 索引类型不匹配:Similarity函数用iloc[]获取行,但传入的是产品编号PN(非整数),而iloc[]仅接受整数位置索引,直接导致越界错误。
  2. 按钮回调绑定错误:button.on_click(get_recommendations(name))会直接执行函数,而非传入回调引用,导致逻辑触发时机错误。

分步修复

1. 修正按钮回调绑定

把直接执行函数改为传递回调引用,用lambda包装参数:

button.on_click(lambda _: get_recommendations(name))

2. 重构相似度计算逻辑

两种可选方案:

  • 方案一:直接传递行数据
    修改Similarity函数,直接接收行对象而非索引:

    def Similarity(rowA, rowB):
        return spatial.distance.cosine(rowA['keywords_bin'], rowB['keywords_bin'])
    

    然后在getNeighbors中调用时传递行对象:

    dist = Similarity(baseItem.iloc[0], row)
    
  • 方案二:通过PN获取整数索引
    如果要保留索引传递逻辑,先把PN转为对应的整数索引:

    # 在getNeighbors中获取基准商品的整数索引
    base_idx = baseItem.index[0]
    # 遍历传递整数索引
    dist = Similarity(base_idx, index)
    

3. 修正推荐结果输出

原代码用PN作为iloc[]的索引,改为通过PN查找行数据:

for neighbor in neighbors:
    product_row = products[products['PN'] == neighbor[0]].iloc[0]
    print(f"{product_row['PN']} | Keywords: {str(product_row['keywords_bin']).strip('[]').replace(' ','')}")

4. 优化选中商品的获取逻辑

无需转置为单行DataFrame,直接用Series更简洁:

new_product = products[products['Item'].str.contains(name)].iloc[0]

完整修复后代码示例

from scipy import spatial
import operator
import ipywidgets as widgets
from IPython.display import display

def Similarity(rowA, rowB):
    return spatial.distance.cosine(rowA['keywords_bin'], rowB['keywords_bin'])

def get_recommendations(name):
    # 捕获商品不存在的情况
    try:
        new_product = products[products['Item'].str.contains(name)].iloc[0]
    except IndexError:
        print(f"未找到包含名称 '{name}' 的商品")
        return
    
    print(f"Selected Item: {new_product['PN']} - {new_product['Item']} - {new_product['Description']} - {new_product['Keywords']} - {new_product['Price']}")
    
    def getNeighbors(baseItem, K):
        distances = []
        for index, row in products.iterrows():
            if row['PN'] != baseItem['PN']:
                dist = Similarity(baseItem, row)
                distances.append((row['PN'], dist))
        
        # 余弦距离越小相似度越高,升序排序
        distances.sort(key=operator.itemgetter(1))
        return distances[:K]
    
    K = 10
    neighbors = getNeighbors(new_product, K)
    
    print('\nRecommended Products: \n')
    for pn, dist in neighbors:
        product = products[products['PN'] == pn].iloc[0]
        print(f"{product['PN']} | Keywords: {str(product['keywords_bin']).strip('[]').replace(' ','')} | Similarity Distance: {dist:.4f}")
    
    print('\n')

# 按钮初始化与绑定
button = widgets.Button(
    description='Get Recommendations',
    disabled=False,
    button_style='',
    tooltip='Get Recommendations'
)
display(button)
# 替换"下拉框变量名"为实际的下拉框控件名称
button.on_click(lambda _: get_recommendations(下拉框变量名.value))

内容的提问来源于stack exchange,提问作者ChelleyG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:22:03