Python/Pandas用另一个datafram中的值替换一个datafram中的元素

2024-05-13 22:46:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个问题,用另一个pandas数据帧的值替换一个pandas数据帧中的元素。很抱歉我发了这么长的帖子。我试着在中间举许多例子来澄清我的问题。我使用python2.7.11(Anaconda 4.0.0,64位)。在

数据

我有一个包含许多用户项对的pandas数据帧。此数据帧(我们称之为初始用户项矩阵)的形式如下:

   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

此外,我有一个只包含user1的用户项对的数据帧。我称之为cold_user_item_matrix,此数据帧的形式如下:

^{pr2}$

接下来,我有一个包含项目的numpy-ndarray,我称之为排名的项目。其形式为:

[9 5 3 4]

最后,我将初始用户项矩阵中的用户1的交互更改为NaN,它给出了以下数据帧(称之为新的用户项矩阵):

   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

我想实现什么?

我想将新用户项目矩阵(当前为NaN)中的用户1项对的交互更改为初始用户项矩阵中特定交互的值,当且仅当项目包含在排名的项目数组中时。然后,所有交互仍然NaN的用户项对(DataFrame的行)都应该被删除(user1-item对,itemId不在排名的项目中)。请看下面的结果集应该是什么样子。在

中间结果:

   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)

它有什么作用?它循环遍历排名的“项目数组中的所有项目。首先,它检查用户1是否与该项(if语句的if部分)进行了交互。如果不是,则转到排名的项数组中的下一项(pass)。如果用户1确实与该项交互(If语句的else部分),则将用户1的交互替换为来自新用户项矩阵的项(当前为NaN),替换为用户1与来自冷用户项矩阵的项的交互值,即1或0(我希望你们都还在我身边)。在

出什么问题了?

if语句的if部分没有给出任何问题。当我试图替换new_user_item_matrix中的值(if语句的else部分)时,它出错了。当替换特定元素(交互作用)时,它不仅替换该元素,而且还替换新用户项矩阵中的所有其他值。为了说明,如果循环开始,它首先循环itemId的9和5,这两个用户1没有交互(因此什么也没有发生)。接下来,它在itemid3上循环,userId 1和itemid3的交互应该从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不在排名的_items数组中,因此它们的真实交互不应该被发现。此外,用户1和itemId 3的交互(a1)将为所有交互填充(即使它们的交互不是1而是0)。在

有谁能帮我吗?在


Tags: 数据项目用户newif矩阵数组nan
1条回答
网友
1楼 · 发布于 2024-05-13 22:46:39

短解

本质上,您希望放弃给定用户的所有项目交互,但仅限于那些排名而非的项目。在

为了使建议的解决方案更具可读性,假设df = initial_user_item_matrix。在

具有布尔条件的简单行选择(在原始df上生成只读视图):

filtered_df = df[(df.userID != 1) | df.itemID.isin(ranked_items)]

类似的解决方案通过删除“无效”行来修改数据帧:

^{pr2}$

使用所有中间结构的逐步解决方案

假设上述所有中间产物都是必需的,则可以获得如下期望的结果:

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

相关问题 更多 >