我的数据帧urm的形状为(96438,3)
user_id anime_id user_rating
0 1 20 7.808497
1 3 20 8.000000
2 5 20 6.000000
3 6 20 7.808497
4 10 20 7.808497
我正在尝试建立项目-用户评分矩阵:
X = urm[["user_id", "anime_id"]].as_matrix()
y = urm["user_rating"].values
n_u = len(urm["user_id"].unique())
n_m = len(urm["anime_id"].unique())
R = np.zeros((n_u, n_m))
for idx, row in enumerate(X):
R[row[0]-1, row[1]-1] = y[idx]
如果代码成功,则矩阵如下所示:(我用0填充了NaN)
在索引user_id中,在列中具有anime_id,并为值定级(我从pivot_table获得了此矩阵)
在某些教程中可以正常工作,但是我有一个
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-278-0e06bd0f3133> in <module>()
15 R = np.zeros((n_u, n_m))
16 for idx, row in enumerate(X):
---> 17 R[row[0]-1, row[1]-1] = y[idx]
IndexError: index 5276 is out of bounds for axis 1 with size 5143
答案 0 :(得分:1)
我假设您具有非连续的用户ID(或电影ID),这意味着存在存在两个索引的索引
在您的情况下,您假设每个值都是连续的(因为您使用唯一值的数量定义维),因此设置了矩阵维,这会导致一些非连续值超出范围
在这种情况下,您有两个选择:
urm["user_id"].max()
,urm["anime_id"].max()
第一种方法的缺点显然是它需要您存储更大的矩阵。另外,您可以使用scipy.sparse
根据您拥有的数据格式(通常称为coordinate matrix format)创建矩阵。
潜在地,您可以执行以下操作:
from scipy import sparse
# scipy expects the data in (value_column, (x, y))
mat = sparse.coo_matrix((urm["user_rating"], (urm["user_id"], urm["anime_id"]))
# if you want it as a dense matrix
dense_mat = mat.todense()
然后,您也可以按照我先前询问的here
的方式处理第二个建议。答案 1 :(得分:1)
我尝试了 dennlinger 的第二条建议,它对我有用。 这是我写的代码:
def id_to_index(df):
"""
maps the values to the lowest consecutive values
:param df: pandas Dataframe with columns user, item, rating
:return: pandas Dataframe with the extra columns index_item and index_user
"""
index_item = np.arange(0, len(df.item.unique()))
index_user = np.arange(0, len(df.user.unique()))
df_item_index = pd.DataFrame(df.item.unique(), columns=["item"])
df_item_index["new_index"] = index_item
df_user_index = pd.DataFrame(df.user.unique(), columns=["user"])
df_user_index["new_index"] = index_user
df["index_item"] = df["item"].map(df_item_index.set_index('item')["new_index"]).fillna(0)
df["index_user"] = df["user"].map(df_user_index.set_index('user')["new_index"]).fillna(0)
return df