【问题标题】:If, elif and else in a dataframe to create a new column如果,elif 和 else 在数据框中创建一个新列
【发布时间】:2020-06-17 09:23:39
【问题描述】:

尝试在我的数据框调用“方法”中创建一个新列。附图中的当前dataFrame:

我正在尝试使用 if/elif/else 以及正则表达式来创建新列,但是当我运行此代码时,我只得到来自 else 语句的值。为什么这不起作用,我该如何解决?

if 'posted' in df2.Full.astype(str) and '/ Outbound' in df2.TPrev.astype(str):
    df2['Method']='Classifieds Homepage Button'
elif 'ad posted' in df2.Full.astype(str) and 'thanks' in df2.TPrev.astype(str):
    df2['Method']='Header after Post'
elif 'ad posted' in df2.Full.astype(str) and '/myaccount/listing-classified Outbound' in df2.TPrev.astype(str):
    df2['Method']='My Listings Button'    
elif 'ad posted' in df2.Full.astype(str) and '/s/' in df2.TPrev.astype(str):
    df2['Method']='SRP'  
elif 'ad posted' in df2.Full.astype(str) and '/myaccount/listing-classified nan' in df2.TPrev.astype(str):
    df2['Method']='My Listings Button'
elif 'ad posted' in df2.Full.astype(str) and '/sell nan nan' in df2.TPrev and '/myaccount/listing-classified nan nan' in df2.Prev.astype(str):
    df2['Method']='My Listings Header'
elif 'ad posted' in df2.Full.astype(str) and '/listing/' in df2.TPrev.astype(str):
    df2['Method']='Detail Page Header'
elif 'ad posted' in df2.Full.astype(str) and '/search/' in df2.TPrev.astype(str):
    df2['Method']='SRP'
else:
    df2['Method']='Ignore'

【问题讨论】:

  • 您的逻辑语句评估为 整个 DataFrame 的 单个 真值,因此您只会将整个列设置为这些值之一.相反,您应该像在stackoverflow.com/questions/19913659/… 中一样使用np.select 在每一行中应用条件逻辑。您可能还希望将语句切换为 df2.Full.astype(str).str.contains('ad posted') 之类的内容,因为它们返回布尔系列。
  • 正如上面的评论所说,每次执行都会覆盖df2['Method']。除了np.select,您可以先创建一个空的df2['Method'] 列,然后使用循环填充您的条件。
  • 您没有阅读 Pandas 文档吗?

标签: python regex pandas if-statement series


【解决方案1】:

正如 cmets 中的人所建议的那样,问题是当您将单个值分配给一列时,您只需将所有列重写为与您分配的值相同的值。 你想做的是:

  1. 不要将每行的类型更改为str,只需更改整个数据框:

    df2.astype(str)

  2. 您需要有一个将在数据帧的每一行上使用的逻辑来确定“方法”列的值。最简单的方法是使用您构建的函数并使用 apply 调用它:

def my_logic(row):
   if 'posted' in row.Full and '/ Outbound' in row.TPrev:
      return "Classified Homepage Button"
   elif 'ad posted' in row.Full and 'thanks' in row.TPrev:
      return 'Header after Post'
   elif 'ad posted' in row.Full and '/myaccount/listing-classified Outbound' in row.TPrev:
      return 'My Listings Button'
   elif 'ad posted' in row.Full and '/s/' in row.TPrev:
      return 'SRP'
   elif 'ad posted' in row.Full and '/myaccount/listing-classified nan' in row.TPrev:
      return 'My Listings Button'
   elif 'ad posted' in row.Full and '/sell nan nan' in row.TPrev and '/myaccount/listing-classified nan nan' in row.Prev:
      return 'My Listings Header'
   elif 'ad posted' in row.Full and '/listing/' in row.TPrev:
      return 'Detail Page Header'
   elif 'ad posted' in row.Full and '/search/' in row.TPrev:
      return 'SRP'
   else:
      return 'Ignore'

df2['Method'] = df2.apply(lambda row: my_logic(row), axis=1)

这将是最简单的转换,但我认为更优雅的解决方案是使用 np.select - 根据您的逻辑创建您的选择列表和 True/False 列表。前 3 个条件的示例:

conditions = [
   ('posted' in df2.Full) & ('/ Outbound' in df2.TPrev),
   ('ad posted' in df2.Full) & ('thanks' in df2.TPrev),
   ('ad posted' in df2.Full) & ('/myaccount/listing-classified Outbound' in df2.TPrev)]
choices = ['"Classified Homepage Button"', 'Header after Post', 'My Listings Button']
df2['Method'] = np.select(conditions, choices, default='Ignore')

【讨论】:

    猜你喜欢
    • 2014-03-09
    • 2020-06-20
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多