【问题标题】:Creating a new column in Dataframe based on multiple lists基于多个列表在 Dataframe 中创建新列
【发布时间】:2021-04-27 04:19:27
【问题描述】:

我正在尝试根据数据中名为“场地类别”的另一列中的值是否出现在特定列表中,在数据框中创建一个新列“BroadCategory”。我有 5 个列表用于填写新列中的值

例如:

df['BroadCategory'] = np.where(df['VenueCategory'].isin(Bar),'Bar','Other') 
df['BroadCategory'] = np.where(df['VenueCategory'].isin(Museum_ArtGallery),'Museum/Art Gallery','Other')
df['BroadCategory'] = np.where(df['VenueCategory'].isin(Public_Transport),'Public Transport','Other')
df['BroadCategory'] = np.where(df['VenueCategory'].isin(Restaurant_FoodVenue),'Restaurant/Food Venue','Other')

我最终希望出现在列表 Bar 中的 VenueCategory 列中的值被标记为“Bar”,而出现在列表 Museum_ArtGallery 中的值被标记为“Museum_ArtGallery”等。我上面的代码没有做到这一点。

我尝试这样做是为了保留我之前填写的值,但它仍然会覆盖我根据之前的条件填写的值:

df['BroadCategory'] = np.where(df[df.VenueCategory!='Other'].isin(Entertainment_Venue),'Entertainment Venue','Other')

如何根据 VenueCategory 列中的值是否出现在指定列表 Bar、Restaurant、Public_Transport、Museum_ArtGallery 等中,用特定值填充 BoardCategory 列?

【问题讨论】:

  • 我试过了,但它给了我一个错误:df['BroadCategory'] = np.where(df[df.BroadCategory!='Other'].isin(Entertainment_Venue),'Entertainment Venue' ,'Other') 错误:值的长度与索引的长度不匹配
  • 您可以尝试查找列的索引,然后使用 .loc 等

标签: python pandas dataframe numpy


【解决方案1】:

支持你的数据是这样的

df=pd.DataFrame({'VenueCategory':['drink','wine','MOMA','MTA','sushi','Hudson']})
Bar=['drink','wine','alcohol']
Museum_ArtGallery=['MOMA','MCM']
Public_Transport=['MTA','MBTA']
Restaurant_FoodVenue=['sushi','chicken']

准备一本字典:

from collections import defaultdict
d=defaultdict(lambda:'other')
d.update({x:'Bar' for x in Bar})
d.update({x:'Museum_ArtGallery' for x in Museum_ArtGallery})
d.update({x:'Public_Transport' for x in Public_Transport})
d.update({x:'Restaurant_FoodVenue' for x in Restaurant_FoodVenue})

新建列并打印结果:

df['BroadCategory']=df['VenueCategory'].apply(lambda x:d[x])
df

【讨论】:

    【解决方案2】:
    venue_list = [['Bar', Bar],
                   ['Museum_ArtGallery',Museum_ArtGallery]
                   #etc
                   ]
    venue_lookup = pd.concat([
        pd.DataFrame({
            'BroadCategory':venue[0],
            'VenueCategory':venue[1]}) for venue in venue_list]
            )
    pd.merge(df, venue_lookup, how='left', on = 'VenueCategory')
    

    【讨论】:

      【解决方案3】:

      您的解决方案已经很接近了。只是为了不覆盖以前的值,您应该获取行的子集并仅在子集上设置新值。

      为此,您可以首先将新列BroadCategory 初始化为“其他”。然后使用 .isin() 函数像您现在使用的一样,通过使用布尔掩码为新列下标来设置每个类别的行子集。代码如下:

      df['BroadCategory'] = 'Other'
      df['BroadCategory'][df['VenueCategory'].isin(Bar)] = 'Bar' 
      df['BroadCategory'][df['VenueCategory'].isin(Museum_ArtGallery)] = 'Museum/Art Gallery'
      df['BroadCategory'][df['VenueCategory'].isin(Public_Transport)] = 'Public Transport'
      df['BroadCategory'][df['VenueCategory'].isin(Restaurant_FoodVenue)] = 'Restaurant/Food Venue'
      df['BroadCategory'][df['VenueCategory'].isin(Entertainment_Venue)] = 'Entertainment Venue'
      

      【讨论】:

        猜你喜欢
        • 2016-02-10
        • 1970-01-01
        • 2021-12-30
        • 2016-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多