来自字典的熊猫数据帧

时间:2013-08-10 12:35:15

标签: python pandas

我有一个用户项评级的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

任何想法都会非常感激:)

5 个答案:

答案 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)