我有一个数据框对象,如下所示:
'Name' 'Book' 'Rating'
'John' 'Moby Dick' 5
'John' 'The Alchemist' 3
'John' 'The Da Vinci Code' 4
'Peter' 'Moby Dick' 4
'Peter' 'Lolita' 5
'Mike' 'The Alchemist' 4
'Mike' 'The Da Vinci Code' 3
我想根据大小为[len('Name')] [len('Book')]的数据创建一个二维数组,该数组的值应为等级。如果某人未对书进行评分,则该值应为零。
5 3 0 4
4 0 5 0
0 4 0 3
在这里,我的第一行对应于John,下一行是Peter,最后一行对应于Mike,第一列对应于Moby Dick,第二对应于炼金术士,第三对应于洛丽塔,第四对应于达芬奇密码。
我尝试了以下方法,对整个对象进行扫描(我相信有两次,以使每个列都匹配)。
import pandas
import numpy
df = read_from_file
uName = df['Name'].unique().tolist()
uBook = df['Book'].unique().tolist()
m = numpy.zeros((len(uName), len(uBook)))
for i in range(0, len(uName)):
for j in range(0, len(uBook)):
x = df.loc[(df['Name'] == uName[i]) & (df['Book'] == uBook[j])]
if x.empty:
m[i][j] = 0
else:
m[i][j] = x.Rating
它给我正确的结果,但是效率极低。我的数据框非常大-约有50,000行,并且运行该代码段需要花费很多时间。您能以更有效的方式帮助我实现这一目标吗?谢谢。
答案 0 :(得分:0)
>>> import pandas as pd
>>> data = pd.DataFrame({'x': ['A', 'A', 'B','B', 'C'], 'y':['q','p','q', 'p', 'q'], 'r': [1, 2, 3, 4, 5]})
>>> data.pivot(values='r', columns='Name', index='Book')
x A B C
y
p 2.0 4.0 NaN
q 1.0 3.0 5.0
或
>>> data.pivot(values='r', columns='x', index='y').fillna(0).values
array([[2., 4., 0.],
[1., 3., 5.]])
如果您的数据框架中的代码应该是这样的:
data.pivot(values='Rating', columns='x', index='y').fillna(0).values
答案 1 :(得分:0)
数据(temp.csv):
Name,Book,Rating
John,Moby Dick, 5
John,The Alchemist, 3
John,The Da Vinci Code, 4
Peter,Moby Dick, 4
Peter,Lolita, 5
Mike,The Alchemist, 4
Mike,The Da Vinci Code, 3
代码:
df = pd.read_csv('temp.csv')
print(df)
print(df.pivot(values='Rating', columns='Book', index='Name').fillna(0))
输出
Book Lolita Moby Dick The Alchemist The Da Vinci Code
Name
John 0.0 5.0 3.0 4.0
Mike 0.0 0.0 4.0 3.0
Peter 5.0 4.0 0.0 0.0