我有一个用户项评级的python字典,如下所示:
sample={'user1': {'item1': 2.5, 'item2': 3.5, 'item3': 3.0, 'item4': 3.5, 'item5': 2.5, 'item6': 3.0},
'user2': {'item1': 2.5, 'item2': 3.0, 'item3': 3.5, 'item4': 4.0},
'user3': {'item2':4.5,'item5':1.0,'item6':4.0}}
我希望将其转换为像
一样的pandas数据框 col1 col2 col3
0 user1 item1 2.5
1 user1 item2 3.5
2 user1 item3 3.0
3 user1 item4 3.5
4 user1 item5 2.5
5 user1 item6 3.0
6 user2 item1 2.5
7 user2 item2 3.0
8 user2 item3 3.5
9 user2 item4 4.0
10 user3 item2 4.5
11 user3 item5 1.0
12 user3 item6 4.0
任何想法都会非常感激:)
答案 0 :(得分:19)
请尝试以下代码:
import pandas
sample={'user1': {'item1': 2.5, 'item2': 3.5, 'item3': 3.0, 'item4': 3.5, 'item5': 2.5, 'item6': 3.0},
'user2': {'item1': 2.5, 'item2': 3.0, 'item3': 3.5, 'item4': 4.0},
'user3': {'item2':4.5,'item5':1.0,'item6':4.0}}
df = pandas.DataFrame([
[col1,col2,col3] for col1, d in sample.items() for col2, col3 in d.items()
])
答案 1 :(得分:13)
我认为您正在进行的操作 - 将表格取消 - 被称为“融化”。在这种情况下,硬件可以由pd.melt
完成,其他一切基本上都是重命名和重新排序:
df = pd.DataFrame(sample).reset_index().rename(columns={"index": "item"})
df = pd.melt(df, "item", var_name="user").dropna()
df = df[["user", "item", "value"]].reset_index(drop=True)
简单地调用DataFrame
会生成具有我们想要的信息但形状错误的内容:
>>> df = pd.DataFrame(sample)
>>> df
user1 user2 user3
item1 2.5 2.5 NaN
item2 3.5 3.0 4.5
item3 3.0 3.5 NaN
item4 3.5 4.0 NaN
item5 2.5 NaN 1.0
item6 3.0 NaN 4.0
因此,让我们将索引提升为真正的列并改进名称:
>>> df = pd.DataFrame(sample).reset_index().rename(columns={"index": "item"})
>>> df
item user1 user2 user3
0 item1 2.5 2.5 NaN
1 item2 3.5 3.0 4.5
2 item3 3.0 3.5 NaN
3 item4 3.5 4.0 NaN
4 item5 2.5 NaN 1.0
5 item6 3.0 NaN 4.0
然后我们可以调用pd.melt
来转换列。如果我们没有指定我们想要的变量名称“user”,它会给它带来无聊的“变量”名称(就像它给数据本身提供无聊的名称“value”)。
>>> df = pd.melt(df, "item", var_name="user").dropna()
>>> df
item user value
0 item1 user1 2.5
1 item2 user1 3.5
2 item3 user1 3.0
3 item4 user1 3.5
4 item5 user1 2.5
5 item6 user1 3.0
6 item1 user2 2.5
7 item2 user2 3.0
8 item3 user2 3.5
9 item4 user2 4.0
13 item2 user3 4.5
16 item5 user3 1.0
17 item6 user3 4.0
最后,我们可以重新排序和重新编号索引:
>>> df = df[["user", "item", "value"]].reset_index(drop=True)
>>> df
user item value
0 user1 item1 2.5
1 user1 item2 3.5
2 user1 item3 3.0
3 user1 item4 3.5
4 user1 item5 2.5
5 user1 item6 3.0
6 user2 item1 2.5
7 user2 item2 3.0
8 user2 item3 3.5
9 user2 item4 4.0
10 user3 item2 4.5
11 user3 item5 1.0
12 user3 item6 4.0
一旦你习惯它, melt
非常有用。通常,在这里,您可以在之前和之后进行重命名/重新排序。
答案 2 :(得分:5)
我使用pd.stack
提供了另一种可能性:
df = pd.DataFrame(sample)
df = df.T.stack().reset_index()
详细说明
In [24]: df = pd.DataFrame(sample)
In [25]: df
Out[25]:
user1 user2 user3
item1 2.5 2.5 NaN
item2 3.5 3.0 4.5
item3 3.0 3.5 NaN
item4 3.5 4.0 NaN
item5 2.5 NaN 1.0
item6 3.0 NaN 4.0
应用stack
会将列轴旋转到已由item
索引的行轴的子级别上。如您所愿user
首先,让我们使用.T
对转置的DataFrame执行操作:
In [34]: df = df.T.stack()
In [35]: df
Out[35]:
user1 item1 2.5
item2 3.5
item3 3.0
item4 3.5
item5 2.5
item6 3.0
user2 item1 2.5
item2 3.0
item3 3.5
item4 4.0
user3 item2 4.5
item5 1.0
item6 4.0
dtype: float64
您期望基本列而不是索引,因此只需重置索引:
In [36]: df = df.reset_index()
In [37]: df
Out[37]:
level_0 level_1 0
0 user1 item1 2.5
1 user1 item2 3.5
2 user1 item3 3.0
3 user1 item4 3.5
4 user1 item5 2.5
5 user1 item6 3.0
6 user2 item1 2.5
7 user2 item2 3.0
8 user2 item3 3.5
9 user2 item4 4.0
10 user3 item2 4.5
11 user3 item5 1.0
12 user3 item6 4.0
答案 3 :(得分:2)
这与DSM提供的melt
解决方案非常相似:
df = DataFrame(sample)
df = df.unstack().dropna().reset_index()
df = df.rename(columns={'level_0':'col1', 'level_1':'col2', 0:'col3'})
答案 4 :(得分:0)
你可以尝试这样做。
temp=[]
for item in sample:
temp.append(pandas.DataFrame(item))
self.results = pandas.concat(temp)