2017-01-31 2 views
4

У меня есть dataframe:Применить функцию к элементу столбца dataframe на основе значения в другом столбце для той же строки?

df = pd.DataFrame(
    {'number': ['10', '20' , '30', '40'], 'condition': ['A', 'B', 'A', 'B']}) 

df = 
    number condition 
0 10   A 
1 20   B 
2 30   A 
3 40   B 

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

df['number'] = df['number'].apply(lambda x: func(x)) 

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

func(n): 
    #if the value in corresponding condition column is equal to some set of values: 
     # do some stuff to n using the value in condition 
     # return new value for n 

для одного числа, и examp Функция ле я хотел бы написать:

number = 10 
condition = A 
def func(num, condition): 
    if condition == A: 
     return num*3 
    if condition == B: 
     return num*4 

func(number,condition) = 15 

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

Примечание: я прочитал документы по адресу np.where(), pandas.loc() и pandas.index(), но я просто не могу понять, как это реализовать на практике.

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

Таким образом, мой ожидается выход:

df = 
    number condition 
0 30   A 
1 80   B 
2 90   A 
3 160   B 

UPDATE: Выше было слишком расплывчатым. Пожалуйста, смотрите следующее:

df1 = pd.DataFrame({'Entries':['man','guy','boy','girl'],'Conflict':['Yes','Yes','Yes','No']}) 


    Entries Conflict 
0 "man" "Yes" 
1 "guy" "Yes" 
2 "boy" "Yes" 
3 "girl" "No 

def funcA(d): 
    d = d + 'aaa' 
    return d 
def funcB(d): 
    d = d + 'bbb' 
    return d 

df1['Entries'] = np.where(df1['Conflict'] == 'Yes', funcA, funcB) 

Output: 
{'Conflict': ['Yes', 'Yes', 'Yes', 'Np'], 
'Entries': array(<function funcB at 0x7f4acbc5a500>, dtype=object)} 

Как я могу применить приведенное выше утверждение np.where принять ряд панд, как упоминалось в комментариях, и производят желаемый результат, показанный ниже:

Желаемая Выход:

Entries Conflict 
0 "manaaa" "Yes" 
1 "guyaaa" "Yes" 
2 "boyaaa" "Yes" 
3 "girlbbb" "No 
+3

Во-первых, ваш код, чтобы создать ФР имеет ошибку, во-вторых, что нужно 'df.apply (лямбда-строку: FUNC (строки [«номер»], строка [» condition ']), axis = 1) 'this будет' apply' row-wise, поэтому вы можете ссылаться на другой столбец. Также не следует прибегать к 'apply', когда существует векторный метод. Вы могли бы сделать 'np.where (df ['condition'] == 'A', df ['num'] * 3, df ['num'] * 4)', но ваш код установки передает строки для номер столбца – EdChum

+0

@EdChum Извинения, ошибка отмечена. Я согласен - код - искаженный ужасный беспорядок, я искренне удивлен, что он работает в половину времени! Итак, я мог бы написать 'df ['number'] = np.where (df [condition '] ==' A ', functionA, functionB)' и определить 'functionA' и' functionB' в другом месте (скажем, выше этой строки) ? – Chuck

+0

Вам необходимо создать эти функции для принятия серии или DataFrame и вернуть либо логический массив, либо массив с такой же длиной, как и исходный df, но вы определили это, поэтому я не могу размышлять о несуществующем коде – EdChum

ответ

2

Я не знаю об использовании pandas.DataFrame.apply, но вы могли бы определить определенное отображение condition:multiplier ключ-значение (если смотреть в multiplier ниже), и передать в вашу функцию. Затем вы можете использовать список понимание для расчета нового number вывода на основе этих условий:

import pandas as pd 
df = pd.DataFrame({'number': [10, 20 , 30, 40], 'condition': ['A', 'B', 'A', 'B']}) 

multiplier = {'A': 2, 'B': 4} 

def func(num, condition, multiplier): 
    return num * multiplier[condition] 

df['new_number'] = [func(df.loc[idx, 'number'], df.loc[idx, 'condition'], 
        multiplier) for idx in range(len(df))] 

Вот результат:

df 
Out[24]: 
    condition number new_number 
0   A  10   30 
1   B  20   80 
2   A  30   90 
3   B  40   160 

Существует вероятность Векторизованных, чисто панды решение, которое более «идеальным «. Но это тоже работает.

0

Поскольку вопрос был в отношении применить функцию к столбцу dataframe для одной и той же строки, что кажется более точным, чтобы использовать панда apply Funtion в сочетании с lambda:

import pandas as pd 
df = pd.DataFrame({'number': [10, 20 , 30, 40], 'condition': ['A', 'B', 'A', 'B']}) 

def func(number,condition): 
    multiplier = {'A': 2, 'B': 4} 
    return number * multiplier[condition] 

df['new_number'] = df.apply(lambda x: func(x['number'], x['condition']), axis=1) 

В этом примере , lambda принимает столбцы «число» и «условие» из dataframe DF и применяет эти столбцы одной и той же строки к функции FUNC с apply.

Это возвращает следующий результат:

df 
Out[10]: 
condition number new_number 
0 A 10 20 
1 B 20 80 
2 A 30 60 
3 B 40 160 

Для случаяUPDATE его также можно использовать панд apply функцию:

df1 = pd.DataFrame({'Entries':['man','guy','boy','girl'],'Conflict':['Yes','Yes','Yes','No']}) 

def funcA(d): 
    d = d + 'aaa' 
    return d 
def funcB(d): 
    d = d + 'bbb' 
    return d 

df1['Entries'] = df1.apply(lambda x: funcA(x['Entries']) if x['Conflict'] == 'Yes' else funcB(x['Entries']), axis=1) 

В этом примере lambda принимает столбцы ' Записи ' и ' Конфликт ' данных dataframe и применяет эти столбцы либо к funcA или funcB той же строки с apply. Условие, если funcA или funcB будет применено к статье if-else в лямбда.

Это возвращает следующий результат:

df 
Out[12]: 


    Conflict Entries 
0 Yes  manaaa 
1 Yes  guyaaa 
2 Yes  boyaaa 
3 No girlbbb 
Смежные вопросы