我在用另一个 pandas DataFrame 的值替换一个 pandas DataFrame 中的元素时遇到问题。很抱歉发了这么长的帖子。我试图举出许多中间示例来阐明我的问题。我使用 Python 2.7.11(Anaconda 4.0.0,64 位)。
数据
我有一个包含许多用户项对的 pandas DataFrame。这个 DataFrame(我们称之为 initial_user_item_matrix)的形式是:
userId itemId interaction
1 1 1 1
2 1 2 0
3 1 3 1
4 1 4 1
5 2 9 1
6 3 3 1
7 3 5 0
此外,我有一个仅包含用户 1 的用户项对的 DataFrame。我将其称为 cold_user_item_matrix,此 DataFrame 的形式为:
userId itemId interaction
1 1 1 1
2 1 2 0
3 1 3 1
4 1 4 1
接下来,我有一个带有项目的 numpy ndarray,我称之为 ranked_items。它的形式是:
[9 5 3 4]
最后,我将 initial_user_item_matrix 中用户 1 的交互更改为 NaN
,它给出了以下 DataFrame(称之为 new_user_item_matrix) :
userId itemId interaction
1 1 1 NaN
2 1 2 NaN
3 1 3 NaN
4 1 4 NaN
5 2 9 1
6 3 3 1
7 3 5 0
我想实现什么?
我想将 new_user_item_matrix(当前为 NaN
)中用户 1 - 项目对的交互更改为 中该特定交互的值>initial_user_item_matrix 当且仅当该项目包含在 ranked_items 数组中。之后,应删除交互仍为 NaN
的所有用户项对(DataFrame 的行)(用户 1 - itemId 不在 ranked_items 中的项对) .请参阅下面的结果集。
中间结果:
userId itemId interaction
1 1 1 NaN
2 1 2 NaN
3 1 3 1
4 1 4 1
5 2 9 1
6 3 3 1
7 3 5 0
最终结果:
userId itemId interaction
3 1 3 1
4 1 4 1
5 2 9 1
6 3 3 1
7 3 5 0
我尝试了什么?
这是我的代码:
for item in ranked_items:
if new_user_item_matrix.loc[new_user_item_matrix['userId']==cold_user].loc[new_user_item_matrix['itemId']==item].empty:
pass
else: new_user_item_matrix.replace(to_replace=new_user_item_matrix.loc[new_user_item_matrix['userId']==1].loc[new_user_item_matrix['itemId']==item].iloc[0,2],value=cold_user_item_matrixloc[cold_user_item_matrix['itemId']==item].iloc[0,2],inplace=True)
new_user_item_matrix.dropna(axis=0,how='any',inplace=True)
它有什么作用?它遍历 ranked_items 数组中的所有项目。首先,它检查用户 1 是否与项目交互(if 语句的 if 部分)。如果不是,则转到 ranked_items 数组中的下一项(通过)。如果用户 1 确实与项目交互(if 语句的 else 部分),则将用户 1 的交互替换为 new_user_item_matrix 中的项目(当前为 NaN
)通过用户 1 与 cold_user_item_matrix 中的项目的交互值,它是 1 或 0(我希望你们都和我在一起)。
出了什么问题?
if 语句的 if 部分没有给出任何问题。当我尝试替换 new_user_item_matrix(if 语句的 else 部分)中的值时出错了。当替换特定元素(交互)时,它不仅会替换该元素,还会替换 new_user_item_matrix 中所有 NaN
的其他值.为了说明这一点,如果循环开始,它首先循环 itemId 的 9 和 5,用户 1 没有与之交互(因此没有任何反应)。接下来,它遍历 itemId 3,userId 1 和 itemId 3 的交互应该从 NaN
变为 0。但它不仅将 userId 1 和 itemId 3 的交互变为 0,而且用户 1 的所有其他 NaN
交互。给出以下结果集:
userId itemId interaction
1 1 1 1
2 1 2 1
3 1 3 1
4 1 4 1
5 2 9 1
6 3 3 1
7 3 5 0
这显然是不正确的,因为 itemId 1 和 2 不在 ranked_items 数组中,因此不应揭示它们真正的相互作用。此外,用户 1 和 itemId 3 的交互 (a 1) 会为所有交互填充(即使它们的交互不是 1 而是 0)。
有人可以帮我吗?
最佳答案
简短的解决方案
本质上,您想要丢弃给定用户的所有项目交互,但仅限于未排名的项目。
为了使建议的解决方案更具可读性,假设 df = initial_user_item_matrix
。
具有 bool 条件的简单行选择(在原始 df
上生成只读 View ):
filtered_df = df[(df.userID != 1) | df.itemID.isin(ranked_items)]
通过删除“无效”行就地修改数据框的类似解决方案:
df.drop(df[(df.userID == 1) & ~df.itemID.isin(ranked_items)].index, inplace=True)
使用所有中间构造的逐步解决方案
假设需要上述所有中间工件,可以按如下方式获得所需的结果:
import pandas as pd
import numpy as np
initial_user_item_matrix = pd.DataFrame([[1, 1, 1],
[1, 2, 0],
[1, 3, 1],
[1, 4, 1],
[2, 9, 1],
[3, 3, 1],
[3, 5, 0]],
columns=['userID', 'itemID', 'interaction'])
print("initial_user_item_matrix\n{}\n".format(initial_user_item_matrix))
ranked_items = np.array([9, 5, 3, 4])
cold_user = 1
cold_user_item_matrix = initial_user_item_matrix.loc[initial_user_item_matrix.userID == cold_user]
print("cold_user_item_matrix\n{}\n".format(cold_user_item_matrix))
new_user_item_matrix = initial_user_item_matrix.copy()
new_user_item_matrix.ix[new_user_item_matrix.userID == cold_user, 'interaction'] = np.NaN
print("new_user_item_matrix\n{}\n".format(new_user_item_matrix))
new_user_item_matrix.ix[new_user_item_matrix.userID == cold_user, 'interaction'] = cold_user_item_matrix.apply(lambda r: r.interaction if r.itemID in ranked_items else np.NaN, axis=1)
print("new_user_item_matrix after replacing\n{}\n".format(new_user_item_matrix))
new_user_item_matrix.dropna(inplace=True)
print("new_user_item_matrix after dropping nans\n{}\n".format(new_user_item_matrix))
产生
initial_user_item_matrix
userID itemID interaction
0 1 1 1
1 1 2 0
2 1 3 1
3 1 4 1
4 2 9 1
5 3 3 1
6 3 5 0
cold_user_item_matrix
userID itemID interaction
0 1 1 1
1 1 2 0
2 1 3 1
3 1 4 1
new_user_item_matrix
userID itemID interaction
0 1 1 NaN
1 1 2 NaN
2 1 3 NaN
3 1 4 NaN
4 2 9 1
5 3 3 1
6 3 5 0
new_user_item_matrix after replacing
userID itemID interaction
0 1 1 NaN
1 1 2 NaN
2 1 3 1
3 1 4 1
4 2 9 1
5 3 3 1
6 3 5 0
new_user_item_matrix after dropping nans
userID itemID interaction
2 1 3 1
3 1 4 1
4 2 9 1
5 3 3 1
6 3 5 0
关于Python/Pandas - 用另一个数据框中的值替换一个数据框中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38371181/