【问题标题】:If function: if column A==1 AND 1 column B is in list X and column C is not null, 1. else, 0if 函数:如果列 A==1 AND 1 列 B 在列表 X 中且列 C 不为空,则为 1。否则,为 0
【发布时间】:2019-10-29 20:01:52
【问题描述】:

我有一个如下所示的数据集:

index  Ind.  Code Code_2
    1     1   NaN      x
    2     0     7    NaN
    3     1     9      z
    4     1   NaN      a
    5     0    11    NaN
    6     1     4    NaN

我还创建了一个列表来指示代码列中的值,如下所示:

Code_List=['7', '9', '11']

我想为指标创建一个新列,只要 Ind. = 1,代码在上面的列表中,代码 2 不为空

我想创建一个包含 if 语句的函数。我试过了,不确定它是否是语法问题,但我不断收到如下属性错误:

def New_Indicator(x):
    if x['Ind.'] == 1 and (x['Code'].isin[Code_List]) or (x['Code_2'].notnull()):
        return 1
    else: 
        return 0

df['NewIndColumn'] = df.apply(lambda x: New_Indicator(x), axis=1)

("'str' 对象没有属性 'isin'", '发生在索引 259') ("'float'对象没有属性'notnull'", '发生在索引 259')

【问题讨论】:

  • 您的预期输出是多少?
  • 使用 apply 和 if 不是处理数据帧的好方法。这就像在一个 numpy 数组上运行一个 for 循环。您可以在整个列上执行导致逻辑序列的操作,并将它们组合起来以获得更干净的结果
  • 基本上,pandas.DataFrame.apply 方法和 axis=1 将循环中的行传递给分配的函数,在这种情况下它的 New_Indicator。问题是当 x 是一行时,x['Ind.'] 不是一个系列,而是“Ind”的值。该行的列,其他列也是如此。你不应该在你的 apply 方法中使用pandas.Series
  • 另外,你这样做的方式,你可以直接传递New_Indicator。无需包装在 lambda 中。

标签: python pandas function lambda attributeerror


【解决方案1】:

问题是在你的函数中,x['Code'] 是一个字符串,而不是一个系列。我建议你使用numpy.where:

ind1 = df['Ind.'].eq(1)

codes = df.Code.isin(code_list)

code2NotNull = df.Code_2.notnull()

mask = ind1 & codes & code2NotNull

df['indicator'] = np.where(mask, 1, 0)

print(df)

输出

   index  Ind.  Code Code_2  indicator
0      1     1   NaN      x          0
1      2     0   7.0    NaN          0
2      3     1   9.0      z          1
3      4     1   NaN      a          0
4      5     0  11.0    NaN          0
5      6     1   4.0    NaN          0

更新(由@splash58 建议):

df['indicator'] = mask.astype(int) 

【讨论】:

  • df['indicator'] = mask.astype(int)
猜你喜欢
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
  • 2018-05-22
相关资源
最近更新 更多