麻烦在熊猫中转动(在R中展开)

时间:2016-10-25 00:10:01

标签: python-3.x pandas pivot tidyr spread

我在pandas中的pd.pivot()或pivot_table()函数遇到了一些问题。

我有这个:

df = pd.DataFrame({'site_id': {0: 'a', 1: 'a', 2: 'b', 3: 'b', 4: 'c', 5:
 'c',6: 'a', 7: 'a', 8: 'b', 9: 'b', 10: 'c', 11: 'c'},
                   'dt': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1,6: 2, 7: 2, 8: 2, 9: 2, 10: 2, 11: 2},
                   'eu': {0: 'FGE', 1: 'WSH', 2: 'FGE', 3: 'WSH', 4: 'FGE', 5: 'WSH',6: 'FGE', 7: 'WSH', 8: 'FGE', 9: 'WSH', 10: 'FGE', 11: 'WSH'},
                   'kw': {0: '8', 1: '5', 2: '3', 3: '7', 4: '1', 5: '5',6: '2', 7: '3', 8: '5', 9: '7', 10: '2', 11: '5'}})


df
Out[140]: 
    dt   eu kw site_id
0    1  FGE  8       a
1    1  WSH  5       a
2    1  FGE  3       b
3    1  WSH  7       b
4    1  FGE  1       c
5    1  WSH  5       c
6    2  FGE  2       a
7    2  WSH  3       a
8    2  FGE  5       b
9    2  WSH  7       b
10   2  FGE  2       c
11   2  WSH  5       c

我想要这个:

dt   site_id   FGE   WSH
 1         a     8     5
 1         b     3     7
 1         c     1     5
 2         a     2     3
 2         b     5     7
 2         c     2     5

我已经尝试了一切!

df.pivot_table(index = ['site_id','dt'], values = 'kw', columns = 'eu')

df.pivot(index = ['site_id','dt'], values = 'kw', columns = 'eu')

应该有效。我也试过unstack():

df.set_index(['dt','site_id','eu']).unstack(level = -1)

2 个答案:

答案 0 :(得分:6)

你的最后一次尝试(unstack)对我来说很好,我不知道为什么它会给你一个问题。 FWIW,我认为使用索引名称而不是级别更具可读性,所以我这样做:

>>> df.set_index(['dt','site_id','eu']).unstack('eu')

            kw    
eu         FGE WSH
dt site_id        
1  a         8   5
   b         3   7
   c         1   5
2  a         2   3
   b         5   7
   c         2   5

但是再一次,你的方式对我来说看起来很好,和@piRSquared的做法差不多(除了他们的答案增加了一些代码来摆脱多指数)。

我认为pivot的问题是你只能传递一个变量而不是一个列表?无论如何,这对我有用:

>>> df.set_index(['dt','site_id']).pivot(columns='eu')

对于pivot_table,主要问题是' kw'是一个对象/字符,pivot_table默认会尝试与numpy.mean聚合。您可能收到错误消息:" DataError:没有要聚合的数字类型"。

但是有一些解决方法。首先,您可以转换为数字类型,然后使用相同的pivot_table命令

>>> df['kw'] = df['kw'].astype(int)
>>> df.pivot_table(index = ['dt','site_id'], values = 'kw', columns = 'eu')

或者您可以更改聚合函数:

>>> df.pivot_table(index = ['dt','site_id'], values = 'kw', columns = 'eu', 
                   aggfunc=sum )

使用字符串可以求和(连接)的事实,即使你不能理解它们。实际上,您可以使用对字符串进行操作的大多数函数(包括lambdas)。

但请注意,pivot_table's aggfunc需要某种减少操作,即使每个单元格只有一个值,所以实际上没有任何要减少的东西!但是代码中有一个需要减少操作的检查,所以你必须做一个。

答案 1 :(得分:5)

df.set_index(['dt', 'site_id', 'eu']).kw \
    .unstack().rename_axis(None, 1).reset_index()

enter image description here