我正在尝试使用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']
答案 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
个对象,这些对象不可散列,因此您无法使用该列表创建集合。