我如何旋转数据框?

2024-11-15 08:36:00
admin
原创
166
摘要:问题描述:什么是支点?我该如何转型?长格式到宽格式?我见过很多关于数据透视表的问题,即使他们不知道。写一个涵盖数据透视表所有方面的规范问题和答案几乎是不可能的……但我打算试一试。现有问题和答案的问题是,问题通常集中在一个细微差别上,而原发帖人很难概括这个细微差别,因此无法使用许多现有的好答案。然而,没有一个答...

问题描述:

  • 什么是支点?

  • 我该如何转型?

  • 长格式到宽格式?

我见过很多关于数据透视表的问题,即使他们不知道。写一个涵盖数据透视表所有方面的规范问题和答案几乎是不可能的……但我打算试一试。


现有问题和答案的问题是,问题通常集中在一个细微差别上,而原发帖人很难概括这个细微差别,因此无法使用许多现有的好答案。然而,没有一个答案试图给出全面的解释(因为这是一项艰巨的任务)。看看我的谷歌搜索中的几个例子:

  1. 如何在 Pandas 中旋转数据框? - 很好的问题和答案。但答案只回答了具体问题,几乎没有解释。

  2. pandas 数据透视表到数据框- OP 关心的是数据透视表的输出,即列的外观。OP 希望它看起来像 R。这对 pandas 用户来说没什么帮助。

  3. pandas 旋转数据框,重复行- 另一个不错的问题,但答案集中在一种方法上,即pd.DataFrame.pivot


设置

我明确地命名了我的列和相关的列值,以对应我将如何在下面的答案中进行调整。

import numpy as np
import pandas as pd
from numpy.core.defchararray import add

np.random.seed([3,1415])
n = 20

cols = np.array(['key', 'row', 'item', 'col'])
arr1 = (np.random.randint(5, size=(n, 4)) // [2, 1, 2, 1]).astype(str)

df = pd.DataFrame(
    add(cols, arr1), columns=cols
).join(
    pd.DataFrame(np.random.rand(n, 2).round(2)).add_prefix('val')
)
print(df)
     key   row   item   col  val0  val1
0   key0  row3  item1  col3  0.81  0.04
1   key1  row2  item1  col2  0.44  0.07
2   key1  row0  item1  col0  0.77  0.01
3   key0  row4  item0  col2  0.15  0.59
4   key1  row0  item2  col1  0.81  0.64
5   key1  row2  item2  col4  0.13  0.88
6   key2  row4  item1  col3  0.88  0.39
7   key1  row4  item1  col1  0.10  0.07
8   key1  row0  item2  col4  0.65  0.02
9   key1  row2  item0  col2  0.35  0.61
10  key2  row0  item2  col1  0.40  0.85
11  key2  row4  item1  col2  0.64  0.25
12  key0  row2  item2  col3  0.50  0.44
13  key0  row4  item1  col4  0.24  0.46
14  key1  row3  item2  col3  0.28  0.11
15  key0  row3  item1  col1  0.31  0.23
16  key0  row0  item2  col3  0.86  0.01
17  key0  row4  item0  col3  0.64  0.21
18  key2  row2  item2  col0  0.13  0.45
19  key0  row2  item0  col4  0.37  0.70

问题

  1. 我为什么会得到ValueError: Index contains duplicate entries, cannot reshape

  2. 我如何进行旋转,df使得col值是列、row值是索引、平均值val0是值?

col   col0   col1   col2   col3  col4
row
row0  0.77  0.605    NaN  0.860  0.65
row2  0.13    NaN  0.395  0.500  0.25
row3   NaN  0.310    NaN  0.545   NaN
row4   NaN  0.100  0.395  0.760  0.24
  1. 我如何才能使缺失值成为0

col   col0   col1   col2   col3  col4
row
row0  0.77  0.605  0.000  0.860  0.65
row2  0.13  0.000  0.395  0.500  0.25
row3  0.00  0.310  0.000  0.545  0.00
row4  0.00  0.100  0.395  0.760  0.24
  1. 我还能得到除了mean“也许”之外的东西吗sum

col   col0  col1  col2  col3  col4
row
row0  0.77  1.21  0.00  0.86  0.65
row2  0.13  0.00  0.79  0.50  0.50
row3  0.00  0.31  0.00  1.09  0.00
row4  0.00  0.10  0.79  1.52  0.24
  1. 我可以一次进行多个聚合吗?

       sum                          mean
col   col0  col1  col2  col3  col4  col0   col1   col2   col3  col4
row
row0  0.77  1.21  0.00  0.86  0.65  0.77  0.605  0.000  0.860  0.65
row2  0.13  0.00  0.79  0.50  0.50  0.13  0.000  0.395  0.500  0.25
row3  0.00  0.31  0.00  1.09  0.00  0.00  0.310  0.000  0.545  0.00
row4  0.00  0.10  0.79  1.52  0.24  0.00  0.100  0.395  0.760  0.24
  1. 我可以对多个值列进行聚合吗?

      val0                             val1
col   col0   col1   col2   col3  col4  col0   col1  col2   col3  col4
row
row0  0.77  0.605  0.000  0.860  0.65  0.01  0.745  0.00  0.010  0.02
row2  0.13  0.000  0.395  0.500  0.25  0.45  0.000  0.34  0.440  0.79
row3  0.00  0.310  0.000  0.545  0.00  0.00  0.230  0.00  0.075  0.00
row4  0.00  0.100  0.395  0.760  0.24  0.00  0.070  0.42  0.300  0.46
  1. 我可以按多列进行细分吗?

item item0             item1                         item2
col   col2  col3  col4  col0  col1  col2  col3  col4  col0   col1  col3  col4
row
row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.605  0.86  0.65
row2  0.35  0.00  0.37  0.00  0.00  0.44  0.00  0.00  0.13  0.000  0.50  0.13
row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.000  0.28  0.00
row4  0.15  0.64  0.00  0.00  0.10  0.64  0.88  0.24  0.00  0.000  0.00  0.00
  1. 或者

item      item0             item1                         item2
col        col2  col3  col4  col0  col1  col2  col3  col4  col0  col1  col3  col4
key  row
key0 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.86  0.00
     row2  0.00  0.00  0.37  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.50  0.00
     row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.00  0.00  0.00
     row4  0.15  0.64  0.00  0.00  0.00  0.00  0.00  0.24  0.00  0.00  0.00  0.00
key1 row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.81  0.00  0.65
     row2  0.35  0.00  0.00  0.00  0.00  0.44  0.00  0.00  0.00  0.00  0.00  0.13
     row3  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.28  0.00
     row4  0.00  0.00  0.00  0.00  0.10  0.00  0.00  0.00  0.00  0.00  0.00  0.00
key2 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.40  0.00  0.00
     row2  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.13  0.00  0.00  0.00
     row4  0.00  0.00  0.00  0.00  0.00  0.64  0.88  0.00  0.00  0.00  0.00  0.00
  1. 我可以聚合列和行一起出现的频率,即“交叉制表”吗?

col   col0  col1  col2  col3  col4
row
row0     1     2     0     1     1
row2     1     0     2     1     2
row3     0     1     0     2     0
row4     0     1     2     2     1
  1. 如何通过仅以两列为基准将 DataFrame 从长转换为宽?鉴于,

np.random.seed([3, 1415])
df2 = pd.DataFrame({'A': list('aaaabbbc'), 'B': np.random.choice(15, 8)})
df2
   A   B
0  a   0
1  a  11
2  a   2
3  a  11
4  b  10
5  b  10
6  b  14
7  c   7

预期应该是这样的

      a     b    c
0   0.0  10.0  7.0
1  11.0  10.0  NaN
2   2.0  14.0  NaN
3  11.0   NaN  NaN
  1. 我如何将多重索引展平为单一索引pivot

   1  2
   1  1  2
a  2  1  1
b  2  1  0
c  1  0  0

   1|1  2|1  2|2
a    2    1    1
b    2    1    0
c    1    0    0

解决方案 1:

以下是我们可以用来转变观点的习语列表

  1. pd.DataFrame.pivot_table

* 具有更直观 API的升级版`groupby`。对于许多人来说,这是首选方法。这也是开发人员想要的方法。
* 指定行级别、列级别、要聚合的值以及执行聚合的函数。
  1. pd.DataFrame.groupby+pd.DataFrame.unstack

* 适用于任何类型的转型的好方法
* 您指定将构成一个组中的透视行级别和列级别的所有列。 然后选择要聚合的其余列和要执行聚合的函数。 最后,选择要`unstack`包含在列索引中的级别。
  1. pd.DataFrame.set_index+pd.DataFrame.unstack

* 对于某些人(包括我自己)来说,它既方便又直观。无法处理重复的分组键。
* 与范例类似`groupby`,我们指定最终将成为行或列级别的所有列,并将其设置为索引。然后我们`unstack`在列中指定我们想要的级别。如果剩余的索引级别或列级别不唯一,则此方法将失败。
  1. pd.DataFrame.pivot

* 非常类似于`set_index`,因为它有重复键限制。API 也非常有限。它只接受`index`、`columns`、的标量值`values`。
* `pivot_table`与我们选择要旋转的行、列和值的方法类似。但是,我们无法聚合,并且如果行或列不唯一,则此方法将失败。
  1. pd.crosstab

* 这是其专门的版本`pivot_table`,其最纯粹的形式是执行多项任务的最直观的方式。
  1. pd.factorize+np.bincount

* 这是一项非常先进的技术,虽然不太为人所知,但速度非常快。它并非在所有情况下都适用,但当您能够使用它并且习惯使用它时,您将获得性能回报。
  1. pd.get_dummies+pd.DataFrame.dot

* 我使用它来巧妙地执行交叉制表。

参见:

  • 重塑和数据透视表— pandas 用户指南


问题 1

为什么我得到ValueError: Index contains duplicate entries, cannot reshape

发生这种情况的原因是 pandas 试图重新索引具有重复条目的columnsindex对象。有多种方法可以执行数据透视。当要求进行数据透视的键有重复时,其中一些方法不太适合。例如:考虑pd.DataFrame.pivot。我知道有重复的条目共享rowcol值:

df.duplicated(['row', 'col']).any()

True

所以当我pivot使用

df.pivot(index='row', columns='col', values='val0')

我得到了上面提到的错误。事实上,当我尝试使用以下命令执行相同任务时,我得到了相同的错误:

df.set_index(['row', 'col'])['val0'].unstack()

示例

对于每个后续问题,我将使用 来回答pd.DataFrame.pivot_table。然后,我将提供执行相同任务的替代方案。

问题 2 和 3

我如何进行旋转,df使得col值是列、row值是索引、平均值val0是值?

  • pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns='col',
    aggfunc='mean')

col   col0   col1   col2   col3  col4
row                                  
row0  0.77  0.605    NaN  0.860  0.65
row2  0.13    NaN  0.395  0.500  0.25
row3   NaN  0.310    NaN  0.545   NaN
row4   NaN  0.100  0.395  0.760  0.24
+ `aggfunc='mean'`是默认值,我不需要设置它。我将其包括在内是为了明确说明。

我如何才能使缺失值为 0?

  • pd.DataFrame.pivot_table

+ `fill_value`默认情况下不设置。我倾向于适当设置。在本例中,我将其设置为`0`。
df.pivot_table(
    values='val0', index='row', columns='col',
    fill_value=0, aggfunc='mean')

col   col0   col1   col2   col3  col4
row
row0  0.77  0.605  0.000  0.860  0.65
row2  0.13  0.000  0.395  0.500  0.25
row3  0.00  0.310  0.000  0.545  0.00
row4  0.00  0.100  0.395  0.760  0.24
  • pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].mean().unstack(fill_value=0)
  • pd.crosstab

pd.crosstab(
    index=df['row'], columns=df['col'],
    values=df['val0'], aggfunc='mean').fillna(0)

问题 4

我还能得到除了mean“也许”之外的东西吗sum

  • pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns='col',
    fill_value=0, aggfunc='sum')

col   col0  col1  col2  col3  col4
row
row0  0.77  1.21  0.00  0.86  0.65
row2  0.13  0.00  0.79  0.50  0.50
row3  0.00  0.31  0.00  1.09  0.00
row4  0.00  0.10  0.79  1.52  0.24
  • pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].sum().unstack(fill_value=0)
  • pd.crosstab

pd.crosstab(
    index=df['row'], columns=df['col'],
    values=df['val0'], aggfunc='sum').fillna(0)

问题 5

我可以一次进行多个聚合吗?

请注意,对于pivot_tablecrosstab我需要传递可调用函数列表。另一方面,groupby.agg能够为有限数量的特殊函数获取字符串。 groupby.agg也会获取我们传递给其他函数的相同可调用函数,但利用字符串函数名称通常更有效,因为可以获得效率。

  • pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns='col',
    fill_value=0, aggfunc=[np.size, np.mean])

     size                      mean
col  col0 col1 col2 col3 col4  col0   col1   col2   col3  col4
row
row0    1    2    0    1    1  0.77  0.605  0.000  0.860  0.65
row2    1    0    2    1    2  0.13  0.000  0.395  0.500  0.25
row3    0    1    0    2    0  0.00  0.310  0.000  0.545  0.00
row4    0    1    2    2    1  0.00  0.100  0.395  0.760  0.24
  • pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].agg(['size', 'mean']).unstack(fill_value=0)
  • pd.crosstab

pd.crosstab(
    index=df['row'], columns=df['col'],
    values=df['val0'], aggfunc=[np.size, np.mean]).fillna(0, downcast='infer')

问题 6

我可以对多个值列进行聚合吗?

  • pd.DataFrame.pivot_table我们通过了values=['val0', 'val1'],但我们本可以完全放弃它

df.pivot_table(
    values=['val0', 'val1'], index='row', columns='col',
    fill_value=0, aggfunc='mean')

      val0                             val1
col   col0   col1   col2   col3  col4  col0   col1  col2   col3  col4
row
row0  0.77  0.605  0.000  0.860  0.65  0.01  0.745  0.00  0.010  0.02
row2  0.13  0.000  0.395  0.500  0.25  0.45  0.000  0.34  0.440  0.79
row3  0.00  0.310  0.000  0.545  0.00  0.00  0.230  0.00  0.075  0.00
row4  0.00  0.100  0.395  0.760  0.24  0.00  0.070  0.42  0.300  0.46
  • pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0', 'val1'].mean().unstack(fill_value=0)

问题 7

我可以按多列进行细分吗?

  • pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns=['item', 'col'],
    fill_value=0, aggfunc='mean')

item item0             item1                         item2
col   col2  col3  col4  col0  col1  col2  col3  col4  col0   col1  col3  col4
row
row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.605  0.86  0.65
row2  0.35  0.00  0.37  0.00  0.00  0.44  0.00  0.00  0.13  0.000  0.50  0.13
row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.000  0.28  0.00
row4  0.15  0.64  0.00  0.00  0.10  0.64  0.88  0.24  0.00  0.000  0.00  0.00
  • pd.DataFrame.groupby

df.groupby(
    ['row', 'item', 'col']
)['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)

问题 8

我可以按多列进行细分吗?

  • pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index=['key', 'row'], columns=['item', 'col'],
    fill_value=0, aggfunc='mean')

item      item0             item1                         item2
col        col2  col3  col4  col0  col1  col2  col3  col4  col0  col1  col3  col4
key  row
key0 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.86  0.00
     row2  0.00  0.00  0.37  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.50  0.00
     row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.00  0.00  0.00
     row4  0.15  0.64  0.00  0.00  0.00  0.00  0.00  0.24  0.00  0.00  0.00  0.00
key1 row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.81  0.00  0.65
     row2  0.35  0.00  0.00  0.00  0.00  0.44  0.00  0.00  0.00  0.00  0.00  0.13
     row3  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.28  0.00
     row4  0.00  0.00  0.00  0.00  0.10  0.00  0.00  0.00  0.00  0.00  0.00  0.00
key2 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.40  0.00  0.00
     row2  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.13  0.00  0.00  0.00
     row4  0.00  0.00  0.00  0.00  0.00  0.64  0.88  0.00  0.00  0.00  0.00  0.00
  • pd.DataFrame.groupby

df.groupby(
    ['key', 'row', 'item', 'col']
)['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
  • pd.DataFrame.set_index因为键集对于行和列都是唯一的

df.set_index(
    ['key', 'row', 'item', 'col']
)['val0'].unstack(['item', 'col']).fillna(0).sort_index(1)

问题 9

我可以聚合列和行一起出现的频率,即“交叉制表”吗?

  • pd.DataFrame.pivot_table

df.pivot_table(index='row', columns='col', fill_value=0, aggfunc='size')

col   col0  col1  col2  col3  col4
row
row0     1     2     0     1     1
row2     1     0     2     1     2
row3     0     1     0     2     0
row4     0     1     2     2     1
  • pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].size().unstack(fill_value=0)
  • pd.crosstab

pd.crosstab(df['row'], df['col'])
  • pd.factorize+np.bincount

# get integer factorization `i` and unique values `r`
# for column `'row'`
i, r = pd.factorize(df['row'].values)
# get integer factorization `j` and unique values `c`
# for column `'col'`
j, c = pd.factorize(df['col'].values)
# `n` will be the number of rows
# `m` will be the number of columns
n, m = r.size, c.size
# `i * m + j` is a clever way of counting the
# factorization bins assuming a flat array of length
# `n * m`.  Which is why we subsequently reshape as `(n, m)`
b = np.bincount(i * m + j, minlength=n * m).reshape(n, m)
# BTW, whenever I read this, I think 'Bean, Rice, and Cheese'
pd.DataFrame(b, r, c)

      col3  col2  col0  col1  col4
row3     2     0     0     1     0
row2     1     2     1     0     2
row0     1     0     1     2     1
row4     2     2     0     1     1
  • pd.get_dummies

pd.get_dummies(df['row']).T.dot(pd.get_dummies(df['col']))

      col0  col1  col2  col3  col4
row0     1     2     0     1     1
row2     1     0     2     1     2
row3     0     1     0     2     0
row4     0     1     2     2     1

问题 10

如何通过仅旋转两列将 DataFrame 从长转换为宽?

  • DataFrame.pivot

第一步是给每一行分配一个数字 - 这个数字将是该值在转置结果中的行索引。这是使用以下方法完成的GroupBy.cumcount

df2.insert(0, 'count', df2.groupby('A').cumcount())
df2

   count  A   B
0      0  a   0
1      1  a  11
2      2  a   2
3      3  a  11
4      0  b  10
5      1  b  10
6      2  b  14
7      0  c   7

第二步,使用新创建的列作为索引来调用DataFrame.pivot

df2.pivot(*df2)
# df2.pivot(index='count', columns='A', values='B')

A         a     b    c
count
0       0.0  10.0  7.0
1      11.0  10.0  NaN
2       2.0  14.0  NaN
3      11.0   NaN  NaN
  • DataFrame.pivot_table

虽然DataFrame.pivot不仅接受列,DataFrame.pivot_table也接受数组,因此GroupBy.cumcount可以直接传递而index无需创建明确的列。

df2.pivot_table(index=df2.groupby('A').cumcount(), columns='A', values='B')

A         a     b    c
0       0.0  10.0  7.0
1      11.0  10.0  NaN
2       2.0  14.0  NaN
3      11.0   NaN  NaN

问题 11

如何将多个索引展平为单个索引pivot

如果使用字符串columns输入object`join`

df.columns = df.columns.map('|'.join)

别的format

df.columns = df.columns.map('{0[0]}|{0[1]}'.format)

解决方案 2:

为了扩展@piRSquared 的答案,问题 10的另一个版本

问题 10.1

数据框:

d = data = {'A': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 3, 6: 5},
 'B': {0: 'a', 1: 'b', 2: 'c', 3: 'a', 4: 'b', 5: 'a', 6: 'c'}}
df = pd.DataFrame(d)

   A  B
0  1  a
1  1  b
2  1  c
3  2  a
4  2  b
5  3  a
6  5  c

输出:

   0     1     2
A
1  a     b     c
2  a     b  None
3  a  None  None
5  c  None  None

使用df.groupbypd.Series.tolist

t = df.groupby('A')['B'].apply(list)
out = pd.DataFrame(t.tolist(),index=t.index)
out
   0     1     2
A
1  a     b     c
2  a     b  None
3  a  None  None
5  c  None  None

或者更好的选择是pd.pivot_table使用df.squeeze.

t = df.pivot_table(index='A',values='B',aggfunc=list).squeeze()
out = pd.DataFrame(t.tolist(),index=t.index)

解决方案 3:

为了更好地理解函数pivot的工作原理,您可以查看Pandas文档中的示例pivot。但是,如果您有重复的索引列(foo- bar)组合(如df第二个示例所示),则会失败:

枢

pivot与函数相反,pivot_tablemean默认支持使用函数进行数据聚合。下面是一个使用sum聚合函数的示例:

数据透视表

解决方案 4:

致电reset_index()(连同add_suffix()

通常,在调用或reset_index()之后需要。例如,进行以下转换(其中一列变为列名)pivot_table`pivot`

水库

您使用以下代码,在之后pivot,为新创建的列名添加前缀,并将索引(在本例中"movies")转换回列并删除轴名称的名称:

df.pivot(index='movie', columns='week', values='sales').add_prefix('week_').reset_index().rename_axis(columns=None)

正如其他答案所提到的,“pivot”可能指两种不同的操作:

  1. 非堆叠聚合(即使结果groupby.agg更宽。)

  2. 重塑(类似于 Excel、reshapenumpy 或pivot_widerR 中的 pivot)

1. 聚合

pivot_table或者crosstab只是未堆叠的groupby.agg操作结果。事实上,源代码表明,在底层,以下内容是正确的:

  • pivot_table= groupby+ unstack(点击此处了解更多信息。)

  • crosstab=pivot_table

注意:您可以使用列名列表作为indexcolumnsvalues参数。

df.groupby(rows+cols)[vals].agg(aggfuncs).unstack(cols)
# equivalently,
df.pivot_table(vals, rows, cols, aggfuncs)
1.1.crosstab是 的一个特例pivot_table;因此是groupby+unstack

以下是等效的:

  • pd.crosstab(df['colA'], df['colB'])

  • df.pivot_table(index='colA', columns='colB', aggfunc='size', fill_value=0)

  • df.groupby(['colA', 'colB']).size().unstack(fill_value=0)

请注意, 的pd.crosstab开销明显更大,因此它比pivot_tablegroupby+都慢得多unstack。事实上,正如这里所述,也比+pivot_table慢。groupby`unstack`

2. 重塑

pivot是一个更有限的版本,pivot_table其目的是将长数据框重塑为长数据框。

df.set_index(rows+cols)[vals].unstack(cols)
# equivalently, 
df.pivot(index=rows, columns=cols, values=vals)
2.1. 按照问题 10 增加行/列

您还可以将问题 10 中的见解应用于多列数据透视表操作。有两种情况:

  • “long-to-long”:通过增加索引来重塑

案例1

代码:

df = pd.DataFrame({'A': [1, 1, 1, 2, 2, 2], 'B': [*'xxyyzz'], 
                   'C': [*'CCDCDD'], 'E': [100, 200, 300, 400, 500, 600]})
rows, cols, vals = ['A', 'B'], ['C'], 'E'

# using pivot syntax
df1 = (
    df.assign(ix=df.groupby(rows+cols).cumcount())
    .pivot(index=[*rows, 'ix'], columns=cols, values=vals)
    .fillna(0, downcast='infer')
    .droplevel(-1).reset_index().rename_axis(columns=None)
)

# equivalently, using set_index + unstack syntax
df1 = (
    df
    .set_index([*rows, df.groupby(rows+cols).cumcount(), *cols])[vals]
    .unstack(fill_value=0)
    .droplevel(-1).reset_index().rename_axis(columns=None)
)
  • “长到宽”:通过增加列来重塑

案例2

代码:

df1 = (
    df.assign(ix=df.groupby(rows+cols).cumcount())
    .pivot(index=rows, columns=[*cols, 'ix'])[vals]
    .fillna(0, downcast='infer')
)
df1 = df1.set_axis([f"{c[0]}_{c[1]}" for c in df1], axis=1).reset_index()

# equivalently, using the set_index + unstack syntax
df1 = (
    df
    .set_index([*rows, df.groupby(rows+cols).cumcount(), *cols])[vals]
    .unstack([-1, *range(-2, -len(cols)-2, -1)], fill_value=0)
)
df1 = df1.set_axis([f"{c[0]}_{c[1]}" for c in df1], axis=1).reset_index()
  • set_index使用+语法的最小情况unstack

案例3

代码:

df1 = df.set_index(['A', df.groupby('A').cumcount()])['E'].unstack(fill_value=0).add_prefix('Col').reset_index()

1 pivot_table()聚合值并将其拆分。具体来说,它从索引和列中创建一个平面列表,groupby()以此列表作为分组器进行调用,并使用传递的聚合器方法进行聚合(默认值为)。然后在聚合之后,它按列的列表mean进行调用。因此在内部, pivot_table = groupby + unstack。此外,如果传递了,则调用。unstack()`fill_value`fillna()

换句话说,产生的方法与下面示例中pv_1产生的方法相同。gb_1

pv_1 = df.pivot_table(index=rows, columns=cols, values=vals, aggfunc=aggfuncs, fill_value=0)
# internal operation of `pivot_table()`
gb_1 = df.groupby(rows+cols)[vals].agg(aggfuncs).unstack(cols).fillna(0, downcast="infer")
pv_1.equals(gb_1) # True

2 次 crosstab()调用pivot_table(),即crosstab = pivot_table。具体来说,它从传递的值数组中构建一个 DataFrame,通过公共索引对其进行过滤并调用pivot_table()。它比 更受限制,pivot_table()因为它只允许像 这样的一维数组values,而不像pivot_table()那样可以有多个列values

解决方案 5:

pandas 中的 pivot 函数具有与 excel 中的 pivot 操作相同的功能。我们可以将数据集从长格式转换为宽格式。

在此处输入图片描述

让我们举个例子

在此处输入图片描述

我们希望将数据集转换为这样一种形式:每个国家/地区都成为一列,新确诊病例作为与国家/地区相对应的值。我们可以使用数据透视函数执行此数据操作。

在此处输入图片描述

透视数据集

pivot_df = pd.pivot(df, index =['Date'], columns ='Country', values =['NewConfirmed'])
## renaming the columns  
pivot_df.columns = df['Country'].sort_values().unique()

我们可以通过重置索引将新列置于与索引列数据相同的级别。

重置索引以修改列级别

pivot_df = pivot_df.reset_index()

在此处输入图片描述

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1247  
  IPD(Integrated Product Development)研发管理体系作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用,助力企业提升产品开发效率、降低成本、增强市场竞争力。深入理解其核心要素,对于企业成功实施 IPD 研发管理体系至关重要。以下将对 IPD 研发管理体系的四大核心要素进行详细解析。...
IPD流程中的charter   19  
  IPD(Integrated Product Development)研发管理体系强调将产品开发视为一个完整的流程,从市场需求出发,整合企业的各种资源,实现产品的快速、高质量交付。在这个过程中,成本控制是至关重要的一环,它直接关系到产品的竞争力和企业的盈利能力。有效的成本控制能够确保在不牺牲产品质量和性能的前提下,降低...
IPD开发流程管理   22  
  IPD(Integrated Product Development)项目管理作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它通过整合跨部门团队,实现从概念到产品上市的全流程高效管理,提升产品竞争力。深入探讨IPD项目管理的六个关键阶段,对于企业理解和运用这一模式,优化产品开发流程具有重要意义。概念阶段概...
IPD概念阶段   29  
  IPD(Integrated Product Development)流程管理作为一种先进的产品开发管理模式,旨在通过整合各种资源,实现产品开发的高效、协同与创新。在这一流程管理体系下,产品质量保障成为企业关注的核心要点之一。有效的产品质量保障策略不仅能够提升产品的市场竞争力,还能为企业赢得良好的声誉和客户忠诚度。接下...
华为IPD   24  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用