根据同一行的其他列中的值将函数应用于dataframe列元素?

时间:2017-01-31 16:02:48

标签: python pandas numpy

我有一个数据框:

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

对于单个数字,我会写一个示例函数:

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()上的文档,但我无法弄清楚如何将其付诸实践。

我正在努力使用函数中引用其他列的语法,因为我需要访问numbercondition列中的两个值。

因此,我的预期输出是:

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

更新:以上内容过于模糊。请参阅以下内容:

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语句来获取评论中提到的pandas系列,并生成如下所示的所需输出:

期望的输出:

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

2 个答案:

答案 0 :(得分:4)

我不知道如何使用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

可能有一种矢量化的纯熊猫解决方案,它更理想。&#34;但这也是有用的。

答案 1 :(得分:2)

由于问题是关于同一行的数据框列的应用功能,将pandas apply功能与{{1}结合使用似乎更准确}:

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) 获取数据框df的列'number''condition',并将同一行的这些列应用于使用lambda函数 func

返回以下结果:

apply

对于 UPDATE case ,也可以使用pandas df Out[10]: condition number new_number 0 A 10 20 1 B 20 80 2 A 30 60 3 B 40 160 函数:

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) 获取数据框df的列'条目''冲突',并将这些列应用于 funcA与lambda相同的行的 funcB 。如果将应用 funcA funcB ,则使用lambda中的apply子句完成该条件。

返回以下结果:

if-else