【问题标题】:Need help applying this function to a Pandas dataframe column需要帮助将此函数应用于 Pandas 数据框列
【发布时间】:2019-05-01 01:18:27
【问题描述】:

我正在尝试通过查找父 asin 的 sku 并计算满足某些条件的行来在我的 allinv_styles 数据框中查找产品的 sku,但我不知道自己在做什么,非常感谢您帮助。

我收到错误消息:“ValueError:只能将大小为 1 的数组转换为 Python 标量。”

我有两个数据框 adgroups_df 和 allinv_styles。

adgroups_df 有一个名为“广告组”的列,其中包含产品的 sku。

SKU 特定于产品的样式和尺寸。喜欢黑色小。一个父 asin 可以有许多 sku 和样式。我正在尝试编写一个函数来计算广告组所代表的样式的缺货百分比。

我的思考过程是:

  • 查找广告组的父类
  • id 广告组样式
  • 查找该行的父行
  • 计算该样式在该父 asin 中有多少行
  • 计算有多少行存货
  • 计算 oos %
  • 返回 oos %
  • 通过将函数应用于每个广告组列来创建新列

这是我的意大利面条代码:

def calc_style_OOS(adgroups):
    for sku in adgroups:
        # find parent asin of ad group sku
        parentasin = allinv_styles.loc[(allinv_styles['sku'] == sku)]['(Parent) ASIN'].item()

        # I tried to print here to debug...
        print(parentasin)

        # find style of sku
        style = allinv_styles.loc[(allinv_styles['sku'] == sku)]['style'].item()

        # how many variations does this style have?
        total_variations = len(allinv_styles.loc[(allinv_styles['(Parent) ASIN'] == parentasin) &
                  (allinv_styles['style'] == style)])

        # how many of these rows have 0 stock?
        oos_variations = len(allinv_styles.loc[(allinv_styles['(Parent) ASIN'] == parentasin) &
                  (allinv_styles['style'] == style) &
                  (allinv_styles['afn-fulfillable-quantity'] < 0)])

        # caclulate oos %

        if total_variations == 0:
        return 0
        else: 
            oos = oos_variations/total_variations
            return oos

adgroups_df['OOS %'] = adgroups_df['Ad Group'].apply(calc_style_OOS)

深入的错误信息:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-37-7ba9d94d5581> in <module>()
----> 1 adgroups_df['OOS %'] = adgroups_df['Ad Group'].apply(calc_style_OOS)

~\Anaconda3\lib\site-packages\pandas\core\series.py in apply(self, func, convert_dtype, args, **kwds)
   2549             else:
   2550                 values = self.asobject
-> 2551                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   2552 
   2553         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/src/inference.pyx in pandas._libs.lib.map_infer()

<ipython-input-36-ac54497ca2ef> in calc_style_OOS(adgroups)
     14     for sku in adgroups:
     15         # find parent asin of ad group sku
---> 16         parentasin = allinv_styles.loc[(allinv_styles['sku'] == sku)]['(Parent) ASIN'].item()
     17         # I tried to print here to debug...
     18         print(parentasin)

~\Anaconda3\lib\site-packages\pandas\core\base.py in item(self)
    717         """
    718         try:
--> 719             return self.values.item()
    720         except IndexError:
    721             # copy numpy's message here because Py26 raises an IndexError

ValueError: can only convert an array of size 1 to a Python scalar

【问题讨论】:

    标签: python pandas dataframe anaconda


    【解决方案1】:

    如果我对问题的理解正确,请更改:

    def calc_style_OOS(adgroups):
        for sku in adgroups:
    

    到这里:

    def calc_style_OOS(sku):
    

    Series.apply 正在按元素应用函数,您不需要 calc_style_OOS 中的循环。

    如果您想在calc_style_OOS 中使用allinv_styles,则需要将allinv_styles 作为参数传递给apply

    adgroups_df['OOS %'] = adgroups_df['Ad Group'].apply(calc_style_OOS, args=(allinv_styles,))
    

    但是,我认为您应该为 (Parent) ASINstyletotal_variationsoos_variations 创建 4 个临时列,而不是在自定义 apply 函数中计算每个列。

    示例(未测试)

    # Map (Parent) ASIN
    adgroups_df['(Parent) ASIN'] = adgroups_df.sku.map(dict(zip(allinv_styles.sku, allinv_styles['(Parent) ASIN'])))
    
    # Map style
    adgroups_df['style'] = adgroups_df.sku.map(dict(zip(allinv_styles.sku, allinv_styles.style)))
    
    # Get variation counts
    group_cols = ['(Parent) ASIN', 'style']
    total_variations = allinv_styles[group_cols].groupby(group_cols).size()
    oos_variations = allinv_styles['afn-fulfillable-quantity'] < 0)][group_cols].groupby(group_cols).size()
    
    # Calculate %, map back to adgroups_df
    oos_percents = oos_variations / total_variations
    oos_percents = oos_percents.where(oos_percents != np.inf, 0)
    adgroups_df = adgroups_df.join(oos_percents, on=group_cols)
    

    【讨论】:

    • 感谢您的帮助!实施您建议的更改后,我收到一个新的关键错误:KeyError: 'Parent ASIN' at ---&gt; 23 total_variations = allinv_styles[['(Parent) ASIN', 'style', 'sku']].groupby(['Parent ASIN', 'style']).transform('count')
    • 非常感谢您一直以来的帮助。我得到: AttributeError: 'DataFrame' 对象在----&gt; 2 adgroups_df['(Parent) ASIN'] = adgroups_df.map(dict(zip(allinv_styles.sku, allinv_styles['(Parent) ASIN']))) 没有属性'map'@
    • 抱歉,错过了skuadgroups_df.sku.map(dict(zip(allinv_styles.sku, allinv_styles['(Parent) ASIN'])))
    【解决方案2】:
    def calc_style_OOS(adgroup):
    
    # edge case ad group not in df
    
    if len(allinv_styles[allinv_styles['sku'].isin([adgroup])]) == 0: 
        return 'No data'
    
    else:
    
        # find parent asin of ad group sku
        parentasin = allinv_styles[['sku','(Parent) ASIN']].drop_duplicates().set_index('sku')['(Parent) ASIN'][adgroup]
        #print(parentasin)
    
        # find style of sku
        style = allinv_styles[['sku', 'style']].drop_duplicates().set_index('sku')['style'][adgroup]
    
        # how many variations does this style have?
        total_variations = len(allinv_styles.loc[(allinv_styles['(Parent) ASIN'] == parentasin) &
                                                 (allinv_styles['style'] == style)])
    
        # how many of these rows have 0 stock?
        oos_variations = len(allinv_styles.loc[(allinv_styles['(Parent) ASIN'] == parentasin) &
                                               (allinv_styles['style'] == style) &
                                               (allinv_styles['afn-fulfillable-quantity'] < 1)])
    
        # caclulate oos %
        if total_variations == 0:
            return 0
        else: 
            return oos_variations/total_variations
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 2023-03-08
      • 2020-08-13
      • 2013-09-15
      相关资源
      最近更新 更多