8

我有两个看起来像这样的数据框:

rating
   BMW  Fiat  Toyota
0    7     2       3
1    8     1       8
2    9    10       7
3    8     3       9

own
   BMW  Fiat  Toyota
0    1     1       0
1    0     1       1
2    0     0       1
3    0     1       1

我最终试图获得一个按品牌使用的平均评级数据透视表。或者是这样的:

            BMW  Fiat  Toyota
Usage                        
0      8.333333    10       3
1      7.000000     2       8

我的方法是像这样合并数据集:

Measure  Rating                Own              
Brand       BMW  Fiat  Toyota  BMW  Fiat  Toyota
0             7     2       3    1     1       0
1             8     1       8    0     1       1
2             9    10       7    0     0       1
3             8     3       9    0     1       1

然后尝试使用评级作为值、拥有作为行和品牌作为列来创建数据透视表。但我一直在处理关键问题。我也尝试过拆分度量或品牌级别,但我似乎无法使用行索引名称作为枢轴键。

我究竟做错了什么?有更好的方法吗?

4

2 回答 2

4

我不是 Pandas 的专家,所以解决方案可能比你想要的更笨拙,但是:

rating = pd.DataFrame({"BMW":[7, 8, 9, 8], "Fiat":[2, 1, 10, 3], "Toyota":[3, 8, 7,9]})
own = pd.DataFrame({"BMW":[1, 0, 0, 0], "Fiat":[1, 1, 0, 1], "Toyota":[0, 1, 1, 1]})

r = rating.unstack().reset_index(name='value')
o = own.unstack().reset_index(name='value')
res = DataFrame({"Brand":r["level_0"], "Rating": r["value"], "Own": o["value"]})
res = res.groupby(["Own", "Brand"]).mean().reset_index()
res.pivot(index="Own", columns="Brand", values="Rating")

# result
# Brand       BMW  Fiat  Toyota
# Own                          
# 0      8.333333    10       3
# 1      7.000000     2       8

另一种解决方案,虽然不是很通用(您可以使用 for 循环,但您必须知道数据框中有哪些值own):

d = []
for o in (0, 1):
    t = rating[own == o]
    t["own"] = o
    d.append(t)

res = pd.concat(d).groupby("own").mean()
于 2013-10-17T20:09:38.793 回答
3

我对自己的问题有一个新的答案(基于 Roman 的初始答案)。关键是要获得所需维度的索引。例如

rating.columns.names = ["Brand"]
rating.index.names = ["n"]
print rating

Brand  BMW  Fiat  Toyota
n                       
0        7     2       3
1        8     1       8
2        9    10       7
3        8     3       9

own.columns.names = ["Brand"]
own.index.names = ["n"]
print own

Brand  BMW  Fiat  Toyota
n                       
0        1     1       0
1        0     1       1
2        0     0       1
3        0     1       1

merged = pd.merge(own.unstack().reset_index(name="Own"), 
                  rating.unstack().reset_index(name="Rating"))
print merged

     Brand  n  Own  Rating
0      BMW  0    1       7
1      BMW  1    0       8
2      BMW  2    0       9
3      BMW  3    0       8
4     Fiat  0    1       2
5     Fiat  1    1       1
6     Fiat  2    0      10
7     Fiat  3    1       3
8   Toyota  0    0       3
9   Toyota  1    1       8
10  Toyota  2    1       7
11  Toyota  3    1       9

然后很容易使用pivot_table命令将其转换为所需的结果:

print merged.pivot_table(rows="Brand", cols="Own", values="Rating")

Own             0  1
Brand               
BMW      8.333333  7
Fiat    10.000000  2
Toyota   3.000000  8

这就是我一直在寻找的。再次感谢罗曼指路。

于 2013-10-23T17:11:59.737 回答