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

时间:2016-09-27 04:20:32

标签: python pandas dataframe series

简单地将其煮沸......

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中添加一个名为“颜色”的列。'如果水果是黄色,则该值为黄色;如果水果为红色,则该值为红色;如果不是红色或黄色,则该值为未知。

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

如果水果在黄色水果数据框中,黄色在列中 如果水果在红色水果数据框中,则红色在列中 如果水果不在这些数据框架中的任何一个,那么' unknown'进入专栏。

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

 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)

错误:

\ 非零(个体经营)     890引发ValueError(" {0}的真值是不明确的。"     891"使用a.empty,a.bool(),a.item(),a.any()或a.all()。" - > 892 .format(self。 class name ))     893     894 bool = 非零

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

1 个答案:

答案 0 :(得分: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")

最后,我最喜欢的方法(虽然可能它有点“聪明”)将使用dict来映射你的值(这是一个特殊的熊猫伎俩),如果没有匹配则会离开NaN找到了,所以你可以用fillna填写这些:

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