使用“设置”功能将列合并为唯一值

时间:2018-07-18 14:59:20

标签: python

我正在尝试使用python 3中的'set'函数将列表中的唯一值放入不同的列中。但是我遇到了错误:“ TypeError:'Series'对象是可变的,因此无法进行哈希处理”。我在这里做错了什么?

样本数据:

id,food 1,food 2,food 3
1,,apples,mango
2,oranges,grapes,oranges
3,bananas,,apples

代码:

df = pd.read_csv('food.csv')
df

# pass
list(set(['apples','apples','oranges']))
# answers: ['apples', 'oranges'] #working

# fails if I pass in a dataframe columns. Why?
df['food_all'] = list(set([df['food 1'],df['food 2'],df['food 3']]))
df['food_all']

输出类似(忽略空格/空值等):

id,food_all
1,['apples','mango']
2,['oranges','grapes']
3,['bananas','apples']

3 个答案:

答案 0 :(得分:1)

您可以使用按行apply

获取一组行值
df.apply(lambda x: list(set(x.dropna())), axis=1)

输出

0      [mango, apples]
1    [grapes, oranges]
2    [bananas, apples]
dtype: object

答案 1 :(得分:1)

这应该有效:

df = pd.read_csv('food.csv')

df['food_all'] = df[['food1','food2','food3']].apply(lambda x: ', '.join(sorted(set(x.dropna().astype(str)), reverse=False)), axis=1).values.tolist()

print(df)

结果:

    food1   food2    food3         food_all
0   apples  apples    mango    mango, apples
1  oranges  grapes  oranges  grapes, oranges
2  bananas  apples     None  bananas, apples

答案 2 :(得分:0)

您需要使用pd.concat(或某些其他方法)为每个DataFrame列中的每个元素创建一个非唯一列表。然后,您可以将非唯一列表传递给set函数。

set(pd.concat([df['food 1'],df['food 2'],df['food 3']]))

编辑

对不起,我第一次阅读问题时误解了您想要的输出。这将为您提供所需的输出:

def get_set(row):
    return set([row['food 1'], row['food 2'], row['food 3']])

df['food_all'] = df.apply(get_set, axis=1)

这是因为,根据错误状态,您只能将可哈希对象传递给集合。如here所述,引用this source,集合在内部使用对象的哈希值,因此传递给集合的任何项目都必须是可哈希的。由于您要用来构建集合的列表中的项目是Series个对象,这些对象不可散列,因此您无法使用该列表创建集合。