我如何旋转数据框?

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

问题描述:

  • 什么是支点?

  • 我该如何转型?

  • 长格式到宽格式?

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


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

  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()

在此处输入图片描述

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用