基于列表和Python字符串的组变量

2024-10-04 09:18:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我的python代码没有返回我所期望的结果,我希望您能帮助我

我有一个数据集,其中包括一个城市中场馆的长列表和一列场馆类别类型(例如“意大利餐厅”)。现在,我想在我的数据框架中增加一列,其中包含更广泛的类别组(“eating”),该类别组基于一个包含字符串的列表进行搜索

我希望通过这四个示例场馆类别在我的数据框架中看到以下输出:

  • “意大利餐厅”→ '吃
  • "床与床,;早餐→ '睡觉的
  • “现代艺术博物馆”→ '观光'
  • “健身房”→ '其他的

我试着用以下方法来解决这个问题:

sleeping = ['bed','hostel','hotel']

eating = ['bar','bistro','cafe','pub','restaurant']

sightseeing = ['museum','theater','zoo']

def catgroup(cat):
    for cat in df['venue_cat']:
        if any(s in cat for s in sleeping):
            return 'sleeping'
        elif any(s in cat for s in eating):
            return 'eating'
        elif any(s in cat for s in sightseeing):
            return 'sightseeing'
        else:
            return 'other'

df['cat_group'] = df['venue_cat'].apply(catgroup)

不幸的是,所有场馆从第一个elif声明返回相同的类别:饮食。 我知道这是第一个elif声明,因为如果我改变elif的顺序(吃还是观光),我只会得到:观光

我很想听听你对这个问题的解决方案,因为我看不出来


Tags: 数据indf列表forreturnany类别
2条回答

您可能没有正确使用函数的cat参数。我希望apply被调用多次(每行一次),因此cat参数已经包含要检查的值(或具有该值的单个元素数组)。通过在df上使用for,实际上是基于整个数据帧的第一行的结果,并对所有函数调用使用相同的值进行响应

在函数中,您的代码类似于switch语句(Python没有这个语句,但是可以很容易地进行模拟)

为了模拟普通的switch语句,我通常定义一个助手函数,如下所示:

def switch(v): yield lambda *c:v in c

在in语句的一次传递中使用:

x = 3
for case in switch(x):
    if case(1):   return "one"
    if case(2,4): return "even"
    if case(3):   return "three"

在本例中,比较条件稍有不同,使用正则表达式而不是cat中的“s”会有好处。因此,让我们定义一个wordSwitch()辅助函数来查找整个单词模式:

import re

def wordSwitch(v): yield lambda *c: any(re.search(r'\b('+w+')\b',v) for w in c)

然后,您的代码可能如下所示:

def catGroup(cat):
    for case in wordSwitch(cat):                 # could need to be cat[0]
        if case(*sleeping):    return "sleeping"
        if case(*eating):      return "eating"
        if case(*sightseeing): return "sightseeing"
    return "other"

注意,尽管我不熟悉.apply(),但我相信它直接接收字段(或行)值,因此您不需要(也可能不必)从df['..']获取数据。您应该尝试打印函数接收到的cat值以确保正确

您还可以将单词列表直接放在case()部分:

for case in wordSwitch(cat):
    if case('bed','hostel','hotel'):                   return "sleeping"
    if case('bar','bistro','cafe','pub','restaurant'): return "eating"
    if case('museum','theater','zoo'):                 return "sightseeing"
return "other"

删除函数中的for循环,以便:

def catgroup(cat):
    if any(s in cat for s in sleeping):
        return 'sleeping'
    elif any(s in cat for s in shopping):
        return 'shopping'
    elif any(s in cat for s in eating):
        return 'eating'
    elif any(s in cat for s in sightseeing):
        return 'sightseeing'
    else:
        return 'other'

df['cat_group'] = df['venue_cat'].apply(catgroup)

相关问题 更多 >