首页 文章

尝试在数据框中创建一个基于键是否在另一个数据帧中的值的pandas系列

提问于
浏览
4

简单地把它煮沸......

Dataframe 1 = yellow_fruits列是fruit_name和location

Dataframe 2 = red_fruits列是fruit_name和location

Dataframe 3 = fruit_montage列是fruit_name,pounds_of_fruit_needed,fresh

假设我想在Dataframe 3中添加一个名为“color”的列 . 如果水果是黄色,则值为黄色;如果水果为红色,则值为红色;如果水果为红色或黄色,则为未知值 .

基本上,伪代码......

如果水果在黄色水果数据框中,则黄色进入列中如果水果位于红色水果数据框中,则红色位于列中如果水果不在任何一个数据框中,则“未知”将出现在列中 .

我的代码产生了一个错误:

if df3['fruit_name'].isin(df1['fruit_name']):
        data = "'yellow"
    elif df3['fruit_name'].isin(df2['fruit_name']):
        data = "red"
    else:
        data = "unknown"

    df3['color'] = pd.Series(data, index = df3.index)

错误:

C:\ Anaconda2 \ lib \ site-packages \ pandas \ core \ generic.pyc in nonzero (self)890 raise ValueError("The truth value of a {0} is ambiguous. " 891 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." - > 892 .format(self . class . name ))893 894 bool = nonzero

ValueError:Series的真值是不明确的 . 使用a.empty,a.bool(),a.item(),a.any()或a.all() .

1 回答

  • 1

    经典的方法是使用您的条件作为索引器:

    df1 = pd.DataFrame({'fruit_name':['banana', 'lemon']})
    df2 = pd.DataFrame({'fruit_name':['strawberry', 'apple']})
    df3 = pd.DataFrame({'fruit_name':['lemon', 'rockmelon', 'apple']})
    
    df3["color"] = "unknown"
    df3["color"][df3['fruit_name'].isin(df1['fruit_name'])] = "yellow"
    df3["color"][df3['fruit_name'].isin(df2['fruit_name'])] = "red"
    df3
    
    #   fruit_name    color
    # 0      lemon   yellow
    # 1  rockmelon  unknown
    # 2      apple      red
    

    更实用的方法是将您的逻辑编写为函数并将其映射到系列中,但这可能会慢得多,因为pandas / numpy的很多速度来自使用向量化操作:

    def get_fruit_color(x):
        if x in df1['fruit_name'].unique():
            data = "yellow"
        elif x in df2['fruit_name'].unique():
            data = "red"
        else:
            data = "unknown"
    
        return data
    
    df3["color"] = df3["fruit_name"].map(get_fruit_color)
    

    一种SQL启发的方法是将映射存储在数据帧中,并进行连接(在pandas中称为合并);这应该是一个非常高效的选择 . 指定 how='left' 表示它将是左连接,因此如果未找到连接条件的匹配项,则该行仍将保留,并带有空值:

    colors = ([(x, 'yellow') for x in df1['fruit_name'].unique()] 
               + [(x, 'red') for x in df2['fruit_name'].unique()])
    colors_df = pd.DataFrame(colors, columns = ['fruit_name', 'color'])
    df3.merge(colors_df, how='left').fillna("unknown")
    

    最后,我最喜欢的方法(虽然可能它有点"clever")将使用dict来映射你的值(这是一个特殊的熊猫伎俩),如果没有找到匹配,这将留下 NaN ,所以你可以用 fillna 填充这些:

    df3["color"] = df3["fruit_name"].map(dict(colors)).fillna("unknown")
    

相关问题