Применение функции к столбцу для создания другого столбца - PullRequest
0 голосов
/ 14 мая 2019

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

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

for i in list(df['segment'].unique()): 
    temp = df.query('segment== "%s"' %i)
    for t in list(temp['area_tipe'].unique()):
        temp2 = temp.query('area_tipe== "%s"' %t)
        a = temp2.quantile(q=0.33)
        b = temp2.quantile(q=0.66)
        def classifierprice(x):
            if float(x) < a:
                rep = 'low'
            elif float(x) > a:
                if float(x) < b:
                    rep = 'medium'
            elif float(x) > b:
                rep = 'high'
            return rep 
        temp2['price_class'] = temp2['price'].map(lambda x: classifierprice(x), axis=1)

TypeError: map() got an unexpected keyword argument 'axis'

При использовании вместо карты я получил ту же ошибку, если удалить ось, как применить, так и карту, я получил следующий код /ошибка:

for i in list(df['segment'].unique()): 
    temp = df.query('segment== "%s"' %i)
    for t in list(temp['area_tipe'].unique()):
        temp2 = temp.query('area_tipe== "%s"' %t)
        a = temp2.quantile(q=0.33)
        b = temp2.quantile(q=0.66)
        def classifierprice(x):
            if float(x) < a:
                rep = 'low'
            elif float(x) > a:
                if float(x) < b:
                    rep = 'medium'
            elif float(x) > b:
                rep = 'high'
            return rep 
        temp2['price_class'] = temp2['price'].map(lambda x: classifierprice(x))

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Кто-нибудь знает, как решить эту проблему?

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

def grow(x):
    if x > 0:
        a = 'growing'
    elif x < 0:
        a = 'declining'
    else:
        a = 'constant'
    return a

insights["text"] = (insights["score"].map(grow))

1 Ответ

1 голос
/ 14 мая 2019

Вам нужно извлечь действительное значение там, с помощью метода .quantile() мы получаем объект серии, содержащий 1 значение, но pandas не понимает, что его единственное значение, по его мнению, мы сравниваем серию и, следовательно, ошибку, мыполучить номер внутри, используя .values[0]

import pandas as pd
import numpy as np

### making some sample data
df = pd.DataFrame({"area_tipe":np.random.choice(["m","n","o"],100)
                    , "price" : np.random.randint(1,10,100)    
                    , "segment":np.random.choice(["p","q","r"],100)})

### keeping the function ot of the for loop
def classifierprice(x, a, b):
    x = float(x)
    if x <= a:
        rep = 'low'
    elif a < x < b:
        rep = 'medium'
    elif x >= b:
        rep = 'high'
    return rep 

for i in list(df['segment'].unique()): 
    temp = df.query('segment== "%s"' %i)
    for t in list(temp['area_tipe'].unique()):
        temp2 = temp.query('area_tipe== "%s"' %t)

        a = temp2.quantile(q=0.33).values[0]
        b = temp2.quantile(q=0.66).values[0]
        temp2['price_class'] = temp2['price'].apply(lambda x: classifierprice(x,a,b))

ВЫХОД:

enter image description here

Вы можете сделать этобез петель, вы получите все выходные df одновременно!- попробуйте это как стартер -

def grouped_classifierprice(df_filt):
    a = df_filt.quantile(q=0.33).values[0]
    b = df_filt.quantile(q=0.66).values[0]
    return df_filt.price.apply(lambda x: classifierprice(x,a,b))

outdf = df.groupby(["area_tipe","segment"]).apply(grouped_classifierprice)
...