在遍历列表时在数据框的一行中添加多个值
Posted
技术标签:
【中文标题】在遍历列表时在数据框的一行中添加多个值【英文标题】:Add multiple values in a row of a dataframe while iterate trough a list 【发布时间】:2020-09-05 16:14:47 【问题描述】:我正在构建一个食物推荐系统,并且我有一个数据框:
df:
meat vegetables cheese ketchup egg...
hamburger 3 5 2 2 1
pasta 0 0 4 0 1
soup 0 2 0 0 0
...
我还有一个列表,其中包含用户不喜欢的成分:
dislike:["cheese", "egg"]
所以我要做的是创建一个函数,它添加一个新行“user_name”,在他/她不喜欢的那些成分中添加 10,在所有其他列中添加 0。输出应该是:
meat vegetables cheese ketchup egg...
hamburger 3 5 2 2 1
pasta 0 0 4 0 1
soup 0 2 0 0 0
new_user 0 0 10 0 10
...
我简化了数据框和列表以使其更全面,但实际上它们更长。
这是我到现在为止写的:
def user_pre(df):
dislike=["cheese","egg"]
for ing in dislike:
df.loc["new_user"]= pd.Series(ing:10)
return df
我“工作”,但只针对不喜欢列表中的最后一个元素。此外,它不会在其他单元格中添加 0,而是添加 Nan。
非常感谢您!
【问题讨论】:
【参考方案1】:我不确定在单个 pandas DataFrame 中将用户与菜肴混合起来有多“健康”,但这样的功能应该可以完成工作:
def insert_user_dislikes(user_name='new_user', df=df, ingredients=['meat', 'egg']):
df.loc[user_name] = [10 if col in ingredients else 0 for col in df.columns]
insert_user_dislikes('new_user', df, ['meat', 'egg'])
编辑 1:我也喜欢 @Fred 的解决方案:
def insert_user_dislikes2(user_name='new_user', df=df, ingredients=['meat', 'egg']):
df.loc[user_name] = 0
df.loc[user_name, ingredients] = 10
insert_user_dislikes('user_name', df, ['meat', 'egg'])
编辑 2:这是 Shubham 的绩效评估解决方案:
def insert_user_dislikes3(user_name='new_user', df=df, ingredients=['meat', 'egg']):
s = pd.Series(
np.where(df.columns.isin(ingredients), 10, 0),
name=user_name, index=df.columns, dtype='int')
return df.append(s)
就性能而言(在非常小的数据集上),列表理解的速度似乎更快:
df = pd.DataFrame([[3, 5, 2, 2, 1],
[0, 0, 4, 0, 1]],
columns=['meat', 'vegetables', 'cheese','ketchup', 'egg'],
index=['hamburger', 'pasta'])
print(timeit.timeit(insert_user_dislikes, number=1000))
0.125
print(timeit.timeit(insert_user_dislikes2, number=1000))
0.547
print(timeit.timeit(insert_user_dislikes3, number=1000))
2.153
【讨论】:
【参考方案2】:我不确定这种方法的效率如何,但这应该可行
dislikes = ["cheese","egg"]
new_user = "Tom"
df.loc[new_user] = 0
for dislike in dislikes:
if dislike not in df.columns:
df[dislike] = 0
df.loc[new_user, dislike] = 10
【讨论】:
【参考方案3】:将 new_user 行 = 设置为零,然后过滤并等于 10。
print(df)
meat vegetables cheese ketchup egg
hamburger 3 5 2 2 1
pasta 0 0 4 0 1
soup 0 2 0 0 0
将 new_user 创建为零。
df.loc["new_user", :] = 0
print(df)
meat vegetables cheese ketchup egg
hamburger 3.0 5.0 2.0 2.0 1.0
pasta 0.0 0.0 4.0 0.0 1.0
soup 0.0 2.0 0.0 0.0 0.0
new_user 0.0 0.0 0.0 0.0 0.0
然后再次过滤并设置为 10。
dislike = ["cheese", "egg"]
df.loc["new_user", dislike] = 10
print(df)
meat vegetables cheese ketchup egg
hamburger 3.0 5.0 2.0 2.0 1.0
pasta 0.0 0.0 4.0 0.0 1.0
soup 0.0 2.0 0.0 0.0 0.0
new_user 0.0 0.0 10.0 0.0 10.0
【讨论】:
【参考方案4】:您可以使用Series.isin
来检查数据框的哪些列值存在于dislike
列表中,然后您可以使用DataFrame.append
将新创建的系列s
附加到原始数据框df
。
用途:
import numpy as np
s = pd.Series(
np.where(df.columns.isin(dislike), 10, 0),
name='new_user', index=df.columns, dtype='int') # create a new pandas series
df = df.append(s)
生成的数据框df
将是:
meat vegetables cheese ketchup egg
hamburger 3 5 2 2 1
pasta 0 0 4 0 1
soup 0 2 0 0 0
new_user 0 0 10 0 10
【讨论】:
以上是关于在遍历列表时在数据框的一行中添加多个值的主要内容,如果未能解决你的问题,请参考以下文章
Vue中Select下拉框用v-model绑定了一个值,用v-for遍历出来多个,改变一个下拉框的选项,其他的都会改变