Нужна помощь в применении этой функции к столбцу данных Pandas - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь найти список продуктов в моем фрейме данных allinv_styles, просматривая родительский ассин для sku и подсчитывая строки, которые соответствуют определенным условиям, но я не знаю, что делаю, и я был бы очень признателен вам заhelp.

Я получаю сообщение об ошибке: «ValueError: могу преобразовать только массив размера 1 в скаляр Python.»

У меня есть два кадра данных adgroups_df иallinv_styles.

adgroups_df имеет столбец под названием «Группа объявлений», в котором содержится артикул товара.

Артикул специфичен для товара по стилю и размеру.Вроде черный маленький.Родитель Асин может иметь много стиля и стиляЯ пытаюсь написать функцию для расчета процента отсутствия на складе стиля, который представляет группа объявлений.

Мой мыслительный процесс таков:

  • найти родительский асин группы объявлений
  • стиль группы объявлений с идентификатором
  • поиск родительского номера этой строки с асин
  • подсчитать, сколько строк этого стиля в этом родительском элементе asin
  • подсчитать, сколько строк имеет запас <0 </li>
  • вычислить oos%
  • return 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

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018
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
0 голосов
/ 29 ноября 2018

Если я правильно понимаю проблему, измените это:

def calc_style_OOS(adgroups):
    for sku in adgroups:

на это:

def calc_style_OOS(sku):

Series.apply применяет функцию поэлементно, вам не нужноцикл в calc_style_OOS.

Вам необходимо передать allinv_styles в качестве аргумента apply, если вы хотите использовать его в calc_style_OOS:

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

Однако ядумаю, что вы должны создать 4 временных столбца для (Parent) ASIN, style, total_variations и oos_variations вместо вычисления каждого из них в пользовательской функции 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...