SC.Pandas 01 | 如何使用Pandas分析地球科学数据?

Introduction

过去的几期推文中我们对Python的基本语法进行了介绍,由于该部分内容的缺失,导致在NumPy的更新中一直受到基本语法的掣肘。

在我们对这些内容基本有了基本了解之后,这次开坑的Pandas部分我们将更加自由和游刃有余地实现更多功能。

Pandas是一个建立在 NumPy 基础之上用于数据分析和操作的 Python 软件库,它为操作数值表格和时间序列提供数据结构和运算操作,并具有一定的可视化能力。

关于Pandas

说起Pandas这个名字,本身就有够奇怪的。为什么一个处理表格的库会叫做「熊猫」?是出于致敬传奇创始人的爱好吗?

实际上,由于Pandas的设计初衷是用于计量经济学的数据分析中,因此从该领域的专业术语「Panel Data」(面板数据)中派生出了Pandas的名字。

此外,还有一个像模像样但是并非事实的说法就是:Pandas指的是「Python Data Analysis」的缩写。

对于地球科学领域而言,我们实际工作中会涉及到各式各样的数据处理。但是我们最终都需要将它们统计出特定的特征以用于描述现象,或解释原理。

如某个要素的均值、总和等,A与B之间的关系,某个时间段内的变化趋势等。

Pandas可以帮助我们快速、高效地处理这些数据,从而便于从中提取有价值的信息。

今天的故事,就从Pandas的基本数据结构和索引开始吧!

Pandas的数据结构

Pandas中有3种基本的数据结构,分别是Series、DataFrame和MultiIndex。

简而言之,Series可以看做一个只有一列的表格;DataFrame则与我们常用的Excel表格类似,是一个较为自由的二维表格;MultiIndex则是一种多级索引的表格结构。

由于MultiIndex的复杂性本期暂不做深入介绍,Series和DataFrame即可满足我们大多数的应用场景。

Series

前面我们提到,Series(序列)可以看做一个只有一列的表格。与一维数组不同,Series拥有行名和列名。

Series和DataFrame既可以使用标签(行、列名)索引,也可以使用位置索引(第M行,第N列),因此可以更便捷地索引和操作数据。

我们可以使用多种方式来创建Series,下面我们来看一些例子。

import pandas as pd

# 使用列表创建Series
temperature = [10, 15, 20, 25, 30]
ser = pd.Series(temperature, index=["2021-01-01", "2021-01-02", "2021-01-03", "2021-01-04", "2021-01-05"], name="Temperature")

print(ser, '\n')
print(ser.index)                # 行索引
print(ser.values)               # 值
print(ser.name)                 # 名称
print(ser.dtype)                # 数据类型
print(ser.shape)                # 形状
print(ser.ndim)                 # 维度
print(ser.size)                 # 大小
2021-01-01    10
2021-01-02    15
2021-01-03    20
2021-01-04    25
2021-01-05    30
Name: Temperature, dtype: int64 

Index(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05'], dtype='object')
[10 15 20 25 30]
Temperature
int64
(5,)
1
5

这里我们使用了列表来创建Series,并指定了行列名。同时,输出了部分Series的基本信息。

我们也可以使用字典和数组等来创建Series:

# 使用数组创建Series
import numpy as np

data = np.random.rand(5) * 10
ser = pd.Series(data)
print(ser, '\n')

# 使用字典创建Series
precipitation = {'2019-01-01': 0.5, '2019-01-02': 0.6, '2019-01-03': 0.7}
ser = pd.Series(precipitation)
print(ser)
0    8.206034
1    4.538582
2    2.943366
3    5.961249
4    1.947226
dtype: float64 

2019-01-01    0.5
2019-01-02    0.6
2019-01-03    0.7
dtype: float64

可以看到,我们使用数组创建Series时没有指定index,因此默认的index是从0开始的。如果我们想指定index,除了创建时对Series()函数传入index参数外,还可以对Series的index参数赋值来指定,name参数和Series的值同理。

而我们使用字典创建时,由于字典的键值本身就存在对应关系,因此字典的key自动成为了index

data = np.random.rand(5) * 10
ser = pd.Series(data)
print(ser, '\n')

ser.name = 'Random Data'                        # 赋值修改Series的name属性
ser.index = ['A', 'B', 'C', 'D', 'E']           # 赋值修改Series的index属性
ser['A'] = 100
print(ser)
0    8.465683
1    9.895826
2    7.659089
3    7.852485
4    0.819119
dtype: float64 

A    100.000000
B      9.895826
C      7.659089
D      7.852485
E      0.819119
Name: Random Data, dtype: float64

DataFrame

DataFrame(数据帧,或数据框)是Pandas中最重要的数据结构,它可以用来存储和处理表格数据。DataFrame可以理解为一组有序的、长度相同的二维数据,每一列可以有不同的类型(数值、字符串、布尔值等)。

使用DataFrame简化数据处理步骤,可以极大地解放我们在Excel中拖表计算的繁琐工作。

DataFrame的创建方式同样多样化,下面我们也来看看简单的例子:

# 使用列表创建DataFrame
temperature = [20, 21, 19, 22, 20, 21, 20]
humidity = [60, 65, 55, 70, 60, 65, 60]
precipitation = [0.5, 0.6, 0.4, 0.7, 0.5, 0.6, 0.5]

df = pd.DataFrame([temperature, humidity, precipitation], index=['temperature', 'humidity', 'precipitation'])
print(df, '\n')

df = df.T
print(df)
                0     1     2     3     4     5     6
temperature    20.0  21.0  19.0  22.0  20.0  21.0  20.0
humidity       60.0  65.0  55.0  70.0  60.0  65.0  60.0
precipitation   0.5   0.6   0.4   0.7   0.5   0.6   0.5 

     temperature  humidity  precipitation
0         20.0      60.0            0.5
1         21.0      65.0            0.6
2         19.0      55.0            0.4
3         22.0      70.0            0.7
4         20.0      60.0            0.5
5         21.0      65.0            0.6
6         20.0      60.0            0.5

这里我们假定了某个地区的气温、湿度和降水,并将这三要素的列表整合到了同一个DataFrame中。由于列表默认按行排列,因此我们使用转置.T对该数据帧进行了旋转(实际上,当我们后面了解了Pandas的索引方式后,就可以按列添加数据而不需要进行这样的操作了)。

# 从数组创建DataFrame
data = np.random.rand(5, 3) * 100
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
print(df, '\n')

# 从字典创建DataFrame
data = {'temperature': [22, 23, 21, 20, 19], 'humidity': [60, 65, 70, 75, 80], 'pressure': [1013, 1015, 1018, 1020, 1022]}
df = pd.DataFrame(data)
print(df)
       A          B          C
0  50.327108   2.472678  77.686190
1  57.443441  79.428833  40.798433
2   7.028998  32.522689  73.435392
3  97.450968  17.192801  62.600331
4  14.854463  63.912453  90.014157 

      temperature  humidity  pressure
0           22        60      1013
1           23        65      1015
2           21        70      1018
3           20        75      1020
4           19        80      1022

数组和字典同样可以创建Pandas数据帧,对于数组而言,其排列方式与DataFrame一致;而字典的键key依然被读取为列名(DataFrame中,实际上列名的差异才代表各数据间的本质区别,而行名只是同一列数据下特定内容的标签),值value则被读取为数据。

我们在使用数组创建DataFrame时,通过传入columns参数指定了列名。这是DataFrame与Series不一样的地方,由于Series只有一列,因此使用name参数来表示唯一的列名。

同样,我们可以通过赋值对columns等参数进行修改、赋值等操作。

data = {'longitude': [10.0, 20.0, 30.0], 
        'latitude': [40.0, 50.0, 60.0], 
        'elevation': [70.0, 80.0, 90.0], 
        'temperature': [100.0, 110.0, 120.0], 
        'humidity': [130.0, 140.0, 150.0], 
        'pressure': [160.0, 170.0, 180.0]
        }

df = pd.DataFrame(data)
print(df, '\n')

df.index = ['A', 'B', 'C']
df.columns = ['Longitude', 'Latitude', 'Elevation', 'Temperature', 'Humidity', 'Pressure']
print(df, '\n')
    longitude  latitude  elevation  temperature  humidity  pressure
0       10.0      40.0       70.0        100.0     130.0     160.0
1       20.0      50.0       80.0        110.0     140.0     170.0
2       30.0      60.0       90.0        120.0     150.0     180.0 

    Longitude  Latitude  Elevation  Temperature  Humidity  Pressure
A       10.0      40.0       70.0        100.0     130.0     160.0
B       20.0      50.0       80.0        110.0     140.0     170.0
C       30.0      60.0       90.0        120.0     150.0     180.0 

Pandas数据索引

学习了NumPy的索引机制后,Pandas是索引机制则也简单明了。但由于行、列名的存在,Pandas的索引机制相较数组更为灵活。

Pandas的索引机制可以分为两类:

  • 标签索引:通过标签(行、列名)来索引数据。

  • 位置索引:通过位置(行、列位置)来索引数据。

下面我们直接通过案例来说明其基本用法:

data = {'longitude': [10.0, 20.0, 30.0], 
        'latitude': [40.0, 50.0, 60.0], 
        'elevation': [70.0, 80.0, 90.0], 
        'temperature': [100.0, 110.0, 120.0], 
        'humidity': [130.0, 140.0, 150.0], 
        'pressure': [160.0, 170.0, 180.0]
        }

df = pd.DataFrame(data)
print(df, '\n')

# 使用标签索引
print(df['longitude'], '\n')                          # 使用中括号索引单列
print(df.loc[:, 'latitude'], '\n')                    # 使用loc索引特定行、列标签
print(df.loc[1, ['temperature', 'pressure']], '\n')   # 索引特定行、列标签
print(df.loc[:2, 'humidity':], '\n')                  # 标签索引的范围为闭区间

# 使用位置索引
print(df.iloc[0, 0], '\n')                            # 使用iloc索引特定行、列位置
print(df.iloc[1:, 1:3], '\n')                         # 位置索引的范围为左闭右开(与数组索引一致)
print(df.iloc[:2, 2:-1:2], '\n')
   longitude  latitude  elevation  temperature  humidity  pressure
0       10.0      40.0       70.0        100.0     130.0     160.0
1       20.0      50.0       80.0        110.0     140.0     170.0
2       30.0      60.0       90.0        120.0     150.0     180.0 

0    10.0
1    20.0
2    30.0
Name: longitude, dtype: float64 

0    40.0
1    50.0
2    60.0
Name: latitude, dtype: float64 

temperature    110.0
pressure       170.0
Name: 1, dtype: float64 

   humidity  pressure
0     130.0     160.0
1     140.0     170.0
2     150.0     180.0 

10.0 

   latitude  elevation
1      50.0       80.0
2      60.0       90.0 

   elevation  humidity
0       70.0     130.0
1       80.0     140.0 

以上就是DataFrame的基本索引操作,Series与之类似。

ser = pd.Series([10.5, 20.7, -5, 3.14, 7.89], index=['a', 'b', 'c', 'd', 'e'], name='Temperature')
print(ser, '\n')

print(ser['a'], '\n')                       # 由于仅有一列,中括号索引默认为行标签
print(ser[['a', 'b', 'c']], '\n')
print(ser.loc['b'], '\n')
print(ser.loc['d':], '\n')
print(ser.iloc[:-1:2], '\n')
a    10.50
b    20.70
c    -5.00
d     3.14
e     7.89
Name: Temperature, dtype: float64 

10.5 

a    10.5
b    20.7
c    -5.0
Name: Temperature, dtype: float64 

20.7 

d    3.14
e    7.89
Name: Temperature, dtype: float64 

a    10.5
c    -5.0
Name: Temperature, dtype: float64 

于是,我们可以使用索引机制来灵活赋值和修改数据。

df = pd.DataFrame()

df['temperature'] = [20, 21, 19, 22, 20, 21, 20]
df['humidity'] = [60, 65, 55, 70, 60, 65, 60]
df['wind_speed'] = [10, 15, 5, 20, 10, 15, 10]
df['rainfall'] = [0, .1, 0, 2, 0, .5, 0]
df['weather'] = 'Sunny'

df.index = ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05', '2020-01-06', '2020-01-07']
print(df, '\n')

df.loc['2020-01-01', 'temperature'] += 273.15
df.loc['2020-01-02', 'rainfall'] *= 1000
df.iloc[3, 1] = 1e4
df.loc['2020-01-04', 'weather'] = 'Rainy'

print(df)
            temperature  humidity  wind_speed  rainfall weather
2020-01-01           20        60          10       0.0   Sunny
2020-01-02           21        65          15       0.1   Sunny
2020-01-03           19        55           5       0.0   Sunny
2020-01-04           22        70          20       2.0   Sunny
2020-01-05           20        60          10       0.0   Sunny
2020-01-06           21        65          15       0.5   Sunny
2020-01-07           20        60          10       0.0   Sunny 

            temperature  humidity  wind_speed  rainfall weather
2020-01-01       293.15        60          10       0.0   Sunny
2020-01-02        21.00        65          15     100.0   Sunny
2020-01-03        19.00        55           5       0.0   Sunny
2020-01-04        22.00     10000          20       2.0   Rainy
2020-01-05        20.00        60          10       0.0   Sunny
2020-01-06        21.00        65          15       0.5   Sunny
2020-01-07        20.00        60          10       0.0   Sunny

后记

结束了NumPy和Python基本语法的学习后,后续我们的内容将具有更为实际的使用价值,本次关于Pandas的引入将为我们后续深入学习Pandas处理各种类型的表格打下基础。

毫无疑问,表格在任何学科中都不可或缺,Pandas为解放手动拖表计算的繁琐操作提供了一种高效、易用、直观的处理方式。后续我们将涉猎表格的计算、数据清洗、平滑去噪、时间序列分析等内容,相较于数组和基本语法这些更为底层的概念,这些内容更贴近我们的实际工作中最直接的工具。相信会有助于我们学习、科研工作的开展。

那么,我们下期再见!

 

Manuscript: RitasCake

Proof: Philero; RitasCake

 

 

获取更多资讯,欢迎订阅微信公众号:Westerlies

跳转和鲸社区,云端运行本文案例。https://www.heywhale.com/mw/project/66221ce2e584e69fbfef87ba

 

ed2a59c23288147ba1059406b7c37b09.jpeg

 

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值