代码之家  ›  专栏  ›  技术社区  ›  Vega

这个产品适合装在纸箱里吗?

  •  0
  • Vega  · 技术社区  · 4 年前

    我有一个带有产品p(尺寸单位为毫米)的数据框:

    | product_id | length | width | height
    | -----------|----------------|-------
    | 100        | 500    | 600   | 700
    | 101        | 800    | 400   | 500
    

    以及带有纸箱c(尺寸单位为毫米)的数据框:

    | carton_id  | length | width | height
    | -----------| --------------|-------|-------
    | 66        | 650    | 650   | 750
    | 67        | 630    | 620   | 705
    | 68        | 750    | 550   | 550
    

    目前我有约1000种产品和约50种不同的纸箱。

    对于每种产品,我需要知道它适合装在哪个纸箱里。

    所以我必须旋转纸箱和/或产品,看看它是否适合每个长度*宽度*高度组合。

    我发现了“背包问题”,但那是多个产品放在一个盒子里,而不是一个产品放在一个盒子里?

    我怎么能对熊猫这样做?

    结果应如下所示:

    | product_id | carton_id
    | -----------| ---------
    | 100        | 66
    | 100        | 67
    
    0 回复  |  直到 3 年前
        1
  •  2
  •   tomtomfox    4 年前
    import itertools
    
    values = carton.values[:, 1:]
    
    combi = [np.column_stack([x,y,z]) 
            for x, y, z in itertools.permutations([values[:,0],values[:,1],values[:,2]])]
    new_values = np.concatenate(combi)
    new_index = carton.carton_id.tolist() * len(combi)
    new = np.column_stack([new_index, new_values])
    new_carton = pd.DataFrame(new, columns=['carton_id', 'length', 'width', 'height'])
    
    
    df = pd.merge(product, new_carton, how='cross', suffixes=('_prod', '_cart'))
    df = df[(df.length_cart>df.length_prod) 
       & (df.width_cart>df.width_prod)
       & (df.height_cart>df.height_prod)]
    df = df[['product_id', 'carton_id']].drop_duplicates()
    
    print(df)
    
       product_id  carton_id
    0         100         66
    1         100         67
    
        2
  •  1
  •   Mustafa Aydın    4 年前

    这里有一种方法:

    # take the `id` columns to indexes
    p = p.set_index("product_id")
    c = c.set_index("carton_id")
    
    # get products row-wise
    pp = p.prod(axis=1).to_numpy()
    cc = c.prod(axis=1).to_numpy()
    
    # compare each row of `pp` against each row of `cc`
    cross_compare = np.less.outer(pp, cc)
    
    # matmul via making use of booleans are integers
    # to select the appropriate carton_id's
    result = cross_compare.dot(c.index + " ")
    
    # put the result into a dataframe
    out = pd.DataFrame({"product_id": p.index, "carton_id": result})
    

    得到

    >>> out
    
       product_id  carton_id
    0         100  66 67 68
    1         101  66 67 68