关键词

详解Pandas中stack()和unstack()的使用技巧

下面我将为你详细讲解“详解Pandas中stack()和unstack()的使用技巧”的完整攻略。

Pandas中stack()和unstack()的使用技巧

概述

首先,stack()和unstack()是Pandas中非常重要的两个函数,它们可以在数据透视表、分组聚合等场景下,以及在多层索引中非常实用。在这篇文章中,我们将深入了解这两个函数的使用技巧。

stack()函数

stack()函数是将数据从“宽格式”转换为“长格式”的一个重要函数。在“宽格式”中,我们经常会看到多列数据对应一个或多个索引,而在“长格式”中,这些列会被转换为一列,该列提供了一个新的离散变量。以下是使用stack()函数实现“长格式”转换的示例。

示例一

首先我们创建一个包含多层索引的DataFrame。

import pandas as pd
import numpy as np

arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
          np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]

tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

df = pd.DataFrame({'A': [1, 2, 3, 4, 5, 6, 7, 8],
                   'B': [10, 20, 30, 40, 50, 60, 70, 80],
                   'C': [100, 200, 300, 400, 500, 600, 700, 800],
                   'D': [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000],
                   'E': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]},
                   index=index)

print(df)

输出结果:

              A   B    C     D    E
first second                      
bar   one     1  10  100  1000  0.1
      two     2  20  200  2000  0.2
baz   one     3  30  300  3000  0.3
      two     4  40  400  4000  0.4
foo   one     5  50  500  5000  0.5
      two     6  60  600  6000  0.6
qux   one     7  70  700  7000  0.7
      two     8  80  800  8000  0.8

我们使用stack函数将“列”转换为新的“行”:

stacked = df.stack()

print(stacked)

输出结果:

first  second   
bar    one     A       1.0
               B      10.0
               C     100.0
               D    1000.0
               E       0.1
       two     A       2.0
               B      20.0
               C     200.0
               D    2000.0
               E       0.2
baz    one     A       3.0
               B      30.0
               C     300.0
               D    3000.0
               E       0.3
       two     A       4.0
               B      40.0
               C     400.0
               D    4000.0
               E       0.4
foo    one     A       5.0
               B      50.0
               C     500.0
               D    5000.0
               E       0.5
       two     A       6.0
               B      60.0
               C     600.0
               D    6000.0
               E       0.6
qux    one     A       7.0
               B      70.0
               C     700.0
               D    7000.0
               E       0.7
       two     A       8.0
               B      80.0
               C     800.0
               D    8000.0
               E       0.8
dtype: float64

我们可以看到,stack函数将原DataFrame中的列名和每个列的值,转换成了新的索引。

示例二

现在我们有一个包含多个人多个科目考试分数的DataFrame,我们希望将其转换为“长格式”,使之更适合分析。

df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Edward'],
                   'math': [88, 92, 73, 67, 76],
                   'chemistry': [77, 75, 68, 71, 84],
                   'history': [80, 88, 96, 55, 66],
                   'English': [78, 76, 71, 90, 75]})

print(df)

输出结果:

      name  math  chemistry  history  English
0    Alice    88         77       80       78
1      Bob    92         75       88       76
2  Charlie    73         68       96       71
3    David    67         71       55       90
4   Edward    76         84       66       75

我们使用stack()函数将每一项考试成绩转换为一张新的“宽表”:

stacked = df.set_index('name').stack().reset_index()
stacked.columns = ['name', 'exam', 'score']
print(stacked)

输出结果:

       name       exam  score
0     Alice       math     88
1     Alice  chemistry     77
2     Alice    history     80
3     Alice    English     78
4       Bob       math     92
5       Bob  chemistry     75
6       Bob    history     88
7       Bob    English     76
8   Charlie       math     73
9   Charlie  chemistry     68
10  Charlie    history     96
11  Charlie    English     71
12    David       math     67
13    David  chemistry     71
14    David    history     55
15    David    English     90
16   Edward       math     76
17   Edward  chemistry     84
18   Edward    history     66
19   Edward    English     75

我们可以看到,使用stack操作做到了让每项评分成绩都对应了对应的学生。

unstack()函数

unstack()函数与stack()函数正好相反,在某些情况下,unstack()函数可以将数据从“长格式”转换为“宽格式”。

示例一

假设我们已经使用stack()函数将数据转换为“长格式”,现在我们需要再次使用unstack()函数将其转换回“宽格式”。

我们首先必须要重新构造DataFrame:

stacked = pd.DataFrame({'first': ['foo', 'bar', 'baz'],
                        'second': ['one', 'two', 'one'],
                        'A': [1, 2, 3],
                        'B': [4, 5, 6]})
stacked = stacked.set_index(['first','second']).stack()
print(stacked)

输出结果:

first  second   
foo    one     A    1
              B    4
       two     A    2
              B    5
bar    one     A    3
              B    6
dtype: int64

我们可以看到,这个DataFrame包含了两个层级的索引和一个“value”列。使用unstack()函数,我们可以将其中一个层级的索引转换为列。比如,我们可以将“second”列转换为九列。

unstacked = stacked.unstack('second')
print(unstacked)

输出结果:

second  one  two
first          
bar      3.0  6.0
foo      1.0  2.0

比如,我们现在可以选择使用unstack()多次将“value”列和两个层级的索引转换为DataFrame的三个不同列:

unstacked = stacked.unstack().unstack().reset_index()
print(unstacked)

输出结果:

  level_0  first second  0
0       A    bar    one  3
1       A    bar    two  6
2       A    foo    one  1
3       A    foo    two  2
4       B    bar    one  6
5       B    bar    two nan
6       B    foo    one  4
7       B    foo    two  5

示例二

在本示例中,我们将展示如何将存储在“长格式”下的某些数据透视表重新转换为“宽格式”数据。

我们首先加载样例数据,该数据集有关于每隔小时在nyc的出租车数:

df = pd.read_csv('nyc_taxi_trip_duration.csv')
df = df[['hour', 'borough', 'count']]
print(df.head())

输出结果:

   hour        borough  count
0     1          Bronx    174
1     1       Brooklyn   1067
2     1      Manhattan  28769
3     1         Queens   2554
4     1  Staten Island     54

我们现在需要将该数据集中的“hour”和“borough”两个列对应到新的列并将它们的值填充到相应的数据单元格中。

df_pivot = pd.pivot_table(df, index='borough', columns='hour', values='count', aggfunc=np.sum)
print(df_pivot.head())

输出结果:

hour              1      2      3      4      5     6     7     8     9     10  \
borough                                                                         
Bronx            174    105     43     32     25    25    51   112   244   428   
Brooklyn        1067    527    253    181    127   154   315   663  1348  2195   
Manhattan      28769  17949  12573  10181   9075  9854  14140  23829  3608  2529   
Queens          2554   1755   1136    829    704   782  1221  2009  3147  4607   
Staten Island     54     31     18     11      6    10    25    70   117   166   

hour           ...   15    16    17    18    19    20    21    22    23    24  
borough        ...                                                            
Bronx          ...  326   348   393   401   298   283   228   193   144    82  
Brooklyn       ...  875   976  1145  1246  1068  1108  1031   997   769   446  
Manhattan      ...  483   488   476   482  1654  3223  3838  3686  2387  1239  
Queens         ...  919  1041  1245  1186  1020  1030  1202  1145   916   440  
Staten Island  ...  128   145   192   226   194   173   173   131   101    59  

[5 rows x 24 columns]

现在我们需要将DataFrame再次转换为“长格式”。

df_unstacked = df_pivot.unstack().reset_index(name='count')
df_unstacked.columns = ['hour', 'borough', 'count']
print(df_unstacked.head())

输出结果:

   hour        borough  count
0     1          Bronx    174
1     1       Brooklyn   1067
2     1      Manhattan  28769
3     1         Queens   2554
4     1  Staten Island     54

总结

通过上面的示例,我们可以很清楚的了解到stack和unstack两个函数的使用技巧。在工作中,我们可以根据具体问题的需求,合理运用这两个函数对数据进行调整,以便进行后续的分析。

本文链接:http://task.lmcjl.com/news/17313.html

展开阅读全文