了解熊猫应用循环行为

时间:2020-02-06 19:52:05

标签: python pandas

编辑:我用一个更简单的案例here重述了这个问题。

我仍然不明白在下面的代码行中是通过x传递序列还是单元格(例如,series [0,0]):

df.apply(lambda x: "Y" if x > 0 else "N")

我假设x是单个值,并且此函数是分段执行的。

但是,这似乎与我最近的申请尝试相矛盾。

现在我有了这个输入数据框:

      DBN Grade   3   4   5
0  01M015     3  30  44  15
1  01M015     4  30  44  15
2  01M015     5  30  44  15
3  01M020     3   0   0  26
4  01M020     4   0   0  26
5  01M020     5   0   0  26

我想像这样添加一个新列:

      DBN Grade   3   4   5 Enrollment?
0  01M015     3  30  44  15           Y
1  01M015     4  30  44  15           Y
2  01M015     5  30  44  15           Y
3  01M020     3   0   0  26           N
4  01M020     4   0   0  26           N
5  01M020     5   0   0  26           Y

但是,以下代码使我失败了:

import pandas as pd

data={'DBN':['01M015','01M015','01M015','01M020','01M020','01M020'],
      'Grade':['3','4','5','3','4','5'],
      '3':['30','30','30','0','0','0'],
      '4':['44','44','44','0','0','0'],
      '5':['15','15','15','26','26','26']}

df = pd.DataFrame(data)

# Failure below!
df['Any Enrollment?'] = df.apply(lambda d: 'Y' if d[d['Grade']] != '0' else 'N')

根据我的理解:在这种情况下,如果我有能力在调试器中检查d['Grade'],它应该显示为'3'。因此,d[d['Grade']]应该解析为d['3'],并且应该可以正常工作。

但是,即使存在Grade,我也得到KeyError: 'Grade'

下面的完整代码以及我的解决方法。

import pandas as pd
import numpy as np

data={'DBN':['01M015','01M015','01M015','01M020','01M020','01M020'],
      'Grade':['3','4','5','3','4','5'],
      '3':['30','30','30','0','0','0'],
      '4':['44','44','44','0','0','0'],
      '5':['15','15','15','26','26','26']}

df = pd.DataFrame(data)

# This line below doesn't work, though I think it should.
df['Any Enrollment?'] = df.apply(lambda d: 'Y' if d[d['Grade']] != '0' else 'N')

# This is my workaround.
def enrollment_bool(*args):
    for index in range(3,6):
        idx = index - 2
        if int(args[0]) == index:
            return "Y" if args[idx] != "0" else "N"

df['Enrollment?'] = np.vectorize(enrollment_bool)(df['Grade'],
                                                  df['3'],
                                                  df['4'],
                                                  df['5'])

请注意,我的问题是关于apply和pandas系列与单元格的一般行为,而不是其他解决此问题的方法

谢谢。

3 个答案:

答案 0 :(得分:1)

apply()函数将一个函数作为参数。然后,它遍历axis(默认值为0,或向下排列),并将该函数应用于每个元素或单元格。当在dataframe上调用时,函数的性质决定是否将轴一起处理(例如,np.sum)(在这种情况下,返回series)还是将函数应用于每个轴。数据框中的元素。在序列上调用时,它实际上循环遍历序列中的每个“单元”或元素,并“应用”或计算函数。

通过传递lambda函数,您可以创建自己的函数。基本上,这只是意味着将序列中的一个元素视为示例中的变量d。然后它将遍历整个系列并将相同的功能分别应用于每个单元格。

答案 1 :(得分:1)

axis=方法中未指定参数.apply()的情况下,将使用默认值0(即axis=0)。

这意味着您的lambda函数中的d将连续获得各个列作为一系列对象。

因此,让我们从第一列d = df["DBN"]开始。您的lambda函数的返回值为

'Y' if d[d['Grade']] != '0' else 'N'

i。 e。

'Y' if df["DBN"][df["DBN"]['Grade']] != '0' else 'N'

现在您可以看到为什么得到错误了

KeyError: ('Grade', 'occurred at index DBN')

-从其df["DBN"]['Grade']部分开始。

您可能想要的东西

df['Any Enrollment?'] = ['Y' if df['Grade'][i] != '0' else 'N' for i in df.index]

答案 2 :(得分:0)

如果要对“等级”列中的每个元素进行操作,则应对包含“等级”的系列进行操作。 下面的代码对我有用:

df['Any Enrollment?'] = df['Grade'].apply(lambda d: 'Y' if d != '0' else 'N')
相关问题