下面我将为你详细讲解“详解Pandas中stack()和unstack()的使用技巧”的完整攻略。
首先,stack()和unstack()是Pandas中非常重要的两个函数,它们可以在数据透视表、分组聚合等场景下,以及在多层索引中非常实用。在这篇文章中,我们将深入了解这两个函数的使用技巧。
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()函数与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