数据分析-Pandas如何重塑数据表
数据表,时间序列数据在数据分析建模中很常见,例如天气预报,空气状态监测,股票交易等金融场景。数据分析过程中重新调整,重塑数据表是很重要的技巧,此处选择Titanic数据,以及巴黎、伦敦欧洲城市空气质量监测 N O 2 NO_2 NO2数据作为样例。
GPT专栏文章:
样例程序代码,需要可获取:
样例分析数据,需要可获取:
数据重排列
拿到表格数据后,很多情况下不能直接就用,还需要对数据进行加工处理。数据加工之前,数据的探查就很重要,最常见的是想把表格的某个属性重新按值的大小排列,看有没有什么特点。
比如在Titanic数据中,想把年龄排序查看下年龄分布特征。可以这样操作:
python
In [1]: titanic.sort_values(by="Age").head()
Out[1]:
PassengerId Survived Pclass ... Fare Cabin Embarked
803 804 1 3 ... 8.5167 NaN C
755 756 1 2 ... 14.5000 NaN S
644 645 1 3 ... 19.2583 NaN C
469 470 1 3 ... 19.2583 NaN C
78 79 1 2 ... 29.0000 NaN S
[5 rows x 12 columns]
有或者,还想联合乘客座舱的等级和年龄,看看不同座舱的分布规律。可以排列多个属性,以列表形式。如下所示:
python
In [2]: titanic.sort_values(by=['Pclass', 'Age'], ascending=False).head()
Out[2]:
PassengerId Survived Pclass ... Fare Cabin Embarked
851 852 0 3 ... 7.7750 NaN S
116 117 0 3 ... 7.7500 NaN Q
280 281 0 3 ... 7.7500 NaN Q
483 484 1 3 ... 9.5875 NaN S
326 327 0 3 ... 6.2375 NaN S
[5 rows x 12 columns]
通过DataFrame.sort_values()
,通过指定列名进行表格数据重排。
单列延展宽表
例如,需要关注不同监测站的 N O 2 NO_2 NO2监测值随时间变化情况,就重排表格,把数据进行延展。以下为图示
为了方便起见,仅空气质量数据表的一个子集,仅关注 N O 2 NO_2 NO2监测值,且也值关注每个监测站的前2个数据情况。
比如no2_subset只保留 N O 2 NO_2 NO2监测值,需Paris 、London和 Antwerpen的前两个记录,结果如下:
python
# filter for no2 data only
In [3]: no2 = air_quality[air_quality["parameter"] == "no2"]
# use 2 measurements (head) for each location (groupby)
In [3]: no2_subset = no2.sort_index().groupby(["location"]).head(2)
In [4]: no2_subset
Out[4]:
city country ... value unit
date.utc ...
2019-04-09 01:00:00+00:00 Antwerpen BE ... 22.5 µg/m³
2019-04-09 01:00:00+00:00 Paris FR ... 24.4 µg/m³
2019-04-09 02:00:00+00:00 London GB ... 67.0 µg/m³
2019-04-09 02:00:00+00:00 Antwerpen BE ... 53.5 µg/m³
2019-04-09 02:00:00+00:00 Paris FR ... 27.4 µg/m³
2019-04-09 03:00:00+00:00 London GB ... 67.0 µg/m³
[6 rows x 6 columns]
那么,每个监测站分别作为一个独立的属性列,可以使用pivot函数,这样操作:
python
In [5]: no2_subset.pivot(columns="location", values="value")
Out[5]:
location BETR801 FR04014 London Westminster
date.utc
2019-04-09 01:00:00+00:00 22.5 24.4 NaN
2019-04-09 02:00:00+00:00 53.5 27.4 67.0
2019-04-09 03:00:00+00:00 NaN NaN 67.0
pivot()函数就是纯粹重排数据的,每列一个值。
pandas支持画不同列数据在同一张图上,共用相同的时间轴。
python
In [6]: no2.head()
Out[6]:
city country location parameter value unit
date.utc
2019-06-21 00:00:00+00:00 Paris FR FR04014 no2 20.0 µg/m³
2019-06-20 23:00:00+00:00 Paris FR FR04014 no2 21.8 µg/m³
2019-06-20 22:00:00+00:00 Paris FR FR04014 no2 26.5 µg/m³
2019-06-20 21:00:00+00:00 Paris FR FR04014 no2 24.9 µg/m³
2019-06-20 20:00:00+00:00 Paris FR FR04014 no2 21.4 µg/m³
In [7]: no2.pivot(columns="location", values="value").plot()
Out[7]: <AxesSubplot: xlabel='date.utc'>
如果需要分析每个监测站的 N O 2 NO_2 NO2监测值和 P M 2.5 PM_{2.5} PM2.5监测值的平均浓度。pivot只是重排表格,需要多值的重新聚合,pivot_table()函数就比较合适,提供聚合函数的功能。
python
In [8]: air_quality.pivot_table(
....: values="value", index="location", columns="parameter", aggfunc="mean"
....: )
....:
Out[8]:
parameter no2 pm25
location
BETR801 26.950920 23.169492
FR04014 29.374284 NaN
London Westminster 29.740050 13.443568
就是熟悉的数据透视表功能。通常对行、列的聚合感兴趣。
python
In [9]: air_quality.pivot_table(
....: values="value",
....: index="location",
....: columns="parameter",
....: aggfunc="mean",
....: margins=True,
....: )
....:
Out[9]:
parameter no2 pm25 All
location
BETR801 26.950920 23.169492 24.982353
FR04014 29.374284 NaN 29.374284
London Westminster 29.740050 13.443568 21.491708
All 29.430316 14.386849 24.222743
事实上,pivot_table和groupby()函数功能,获得相同的结果。
python
air_quality.groupby(["parameter", "location"]).mean()
宽表聚到单列
相反的,如果想把宽表合道一个列里头,又该怎么办?
开始之前,先把表格弄成左边图的样子,用前面的知识。
python
In [10]: no2_pivoted = no2.pivot(columns="location", values="value").reset_index()
In [11]: no2_pivoted.head()
Out[11]:
location date.utc BETR801 FR04014 London Westminster
0 2019-04-09 01:00:00+00:00 22.5 24.4 NaN
1 2019-04-09 02:00:00+00:00 53.5 27.4 67.0
2 2019-04-09 03:00:00+00:00 54.5 34.2 67.0
3 2019-04-09 04:00:00+00:00 34.5 48.5 41.0
4 2019-04-09 05:00:00+00:00 46.5 59.5 41.0
好了,现在老子就想把所有的 N O 2 NO_2 NO2监测值给我堆成一列。老板:不要问为什么!不用喷他,直接show结果,代码如下:
python
In [12]: no_2 = no2_pivoted.melt(id_vars="date.utc")
In [13]: no_2.head()
Out[13]:
date.utc location value
0 2019-04-09 01:00:00+00:00 BETR801 22.5
1 2019-04-09 02:00:00+00:00 BETR801 53.5
2 2019-04-09 03:00:00+00:00 BETR801 54.5
3 2019-04-09 04:00:00+00:00 BETR801 34.5
4 2019-04-09 05:00:00+00:00 BETR801 46.5
用melt()就能妥妥的完成任务,从宽表汇聚成1列,搞定。
如果遇到强迫症,需要把列名称和原来列属性更换名字,就还可以做的更好:
python
In [15]: no_2 = no2_pivoted.melt(
....: id_vars="date.utc",
....: value_vars=["BETR801", "FR04014", "London Westminster"],
....: value_name="NO_2",
....: var_name="id_location",
....: )
....:
In [16]: no_2.head()
Out[16]:
date.utc id_location NO_2
0 2019-04-09 01:00:00+00:00 BETR801 22.5
1 2019-04-09 02:00:00+00:00 BETR801 53.5
2 2019-04-09 03:00:00+00:00 BETR801 54.5
3 2019-04-09 04:00:00+00:00 BETR801 34.5
4 2019-04-09 05:00:00+00:00 BETR801 46.5
以上代码只是一个简单示例,示例代码中的表达式可以根据实际问题进行修改。
样例程序代码,需要可获取:
样例分析数据,需要可获取:
觉得有用 收藏 收藏 收藏
点个赞 点个赞 点个赞
End
GPT专栏文章:
GPT实战系列-ChatGLM3本地部署CUDA11+1080Ti+显卡24G实战方案
GPT实战系列-LangChain + ChatGLM3构建天气查询助手
GPT实战系列-大模型为我所用之借用ChatGLM3构建查询助手
GPT实战系列-P-Tuning本地化训练ChatGLM2等LLM模型,到底做了什么?(二)
GPT实战系列-P-Tuning本地化训练ChatGLM2等LLM模型,到底做了什么?(一)
GPT实战系列-ChatGLM2部署Ubuntu+Cuda11+显存24G实战方案