Python/Pandas - 用另一个数据框中的值替换一个数据框中的元素

标签 python python-2.7 numpy pandas dataframe

我在用另一个 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/

相关文章:

python - 从元组列表中删除排列

python - 为什么 Spyder 不遵守我的 IPython 配置文件?

python - 如何让 python Zookeeper api 工作?

python - 为什么当我使用 pygame.key.get_pressed() 时我的角色只向左移动?

python - 看不到postgresql数据库访问程序的输出

python - 如何调用右侧定义的类中存在的方法。 Python继承。多重继承。 Dimond场景python继承

python - 从矩阵中获取具有最大和值的列

python - 在 Python 中绘制多项式

python - 列出相邻单元格

python - Python中的第三方titlecase方法