Pandas 使用详解

444 阅读7分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。

Pandas 介绍

Pandas 是一个第三方模块,专门用来数据处理。Pandas 有很多强大的功能,我们可以用来处理 csv 和 excel 文件。我们可以用它进行数据的统计、查找等操作。因为是第三方模块,使用前我们需要安装一下:

pip install pandas

然后我们可以尝试一下 Pandas 的基本操作了。我们先看下面的代码:

import pandas as pd

# 创建一个 DataFrame 对象
df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1}
])
print(df)

在代码中,我们创建了一个 DataFrame 对象,什么是 DataFrame 这个我们在后面会详细说。参数我们传入了一个元素为字典的列表,我们看一下输出结果:

  city  temperature
0   南昌            2
1   武汉           -1

可以看到显示效果类似于一张表,而且输出为我们添加了一个行索引。如果你使用 Jupyter 的话,显示效果会更加美观。 上面我们只是把全部数据输出,我们也可以选择性输出:

import pandas as pd

# 创建一个 DataFrame 对象
df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1}
])
print(df.head(1))

这次我们调用了一个 df.head() 方法,传入参数 1,表示从头开始取 1 行数据,输出结果如下:

  city  temperature
0   南昌            2

除了查看整行数据,我们还可以索引特定的列:

import pandas as pd

# 创建一个 DataFrame 对象
df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1}
])
print(df['city'])

比如上面代码我们就索引了 city 列,输出结果如下:

0    南昌
1    武汉
Name: city, dtype: object

除了这种普通方式,我们还可以进行条件索引。详细的操作会在后续讲到,下面我们就正式来看看 pandas 的操作吧!

Pandas 的数据结构

数据结构我们可以理解为数据类型,也就是 Pandas 中定义的一些特殊类型。其中有两个我们经常会使用到,一个是 Series,另外一个就是我们上面使用到的 DataFrame 了。那它们都是什么呢?又都有什么区别呢?

Series

其实 Series 就是一个一维的数据,它类似与一个列表,但是又和列表又很多不同。我们先看下面的代码:

import pandas as pd
# 创建一个 Series 对象
s = pd.Series([1, 2, 3, 4], dtype='float32')
print(s)

在创建 Series 时,我们指定了一个 dtype 参数,也是就 Series 的数据类型。dtype 参数不是必须的,当指定 dtype 参数后我们的 Series 对象只能存储指定类型的数据。这也是它和 list 不同的地方。

下面是输出结果:

0    1.0
1    2.0
2    3.0
3    4.0
dtype: float32

那我们来看看 Series 有些什么操作:

import pandas as pd
# 创建 Series 对象
s = pd.Series([1, 2, 3, 4, 4, 4], dtype='float32')
# 查看头一行元素
print(s.head(1))
# 计算 Series 长度
print(s.count())
# 查看数据类型
print(s.dtype)
# 查看数据
print(s.values)
# 查看索引
print(s.index)
# 查看数据大小(和 cout 类似)
print(s.size)

下面是输出结果:

0    1.0
dtype: float32
6
float32
[1. 2. 3. 4. 4. 4.]
6
RangeIndex(start=0, stop=6, step=1)

这里又几个需要注意,其中 s.values 获取的是一个 ndarray 对象。而 index 获取的是 Series 的索引,是一个 pandas.core.indexes.range.RangeIndex 对象,这是 Pandas 中定义的一个特殊对象。

除了上面的操作,Series 还有许多统计函数:

import pandas as pd

s = pd.Series([1, 2, 3, 4, 4, 4], dtype='float32')
# 求平均值
print(s.mean())
# 求最大值
print(s.max())
# 求最小值
print(s.min())
# 求标准差
print(s.std())

输出结果如下:

3.0
4.0
1.0
1.264911

上面的操作很好理解,这里就不解释了。下面我们看看 Series 的索引和切片操作,这是我们经常会使用的操作:

import pandas as pd

s = pd.Series(['a', 'b', 'c', 'd', 'e', 'f'])

# 索引
print(s[3])
# 切片
print(s[0: 2])
# 用 iloc 索引和切片
print(s.iloc[0])
print(s.iloc[0: 2])
# 用 loc 索引和切片
print(s.loc[0])
print(s.loc[0: 2])
# 通过值来索引切片
print(s.loc['a':'c'])

上面我们用了四种方式索引切片,其中[]是最简单的。而 iloc 和 loc 是 Pandas 提供的两个方法,它们都可以用来索引切片。两个方法都可以通过下标索引切片,但是如果想通过内容索引切片,则需要使用 loc 方法。

在上面介绍的很多方法,在 DataFrame 中也是通用的。我们后面会说到,下面我们来看看 DataFrame。

DataFrame

DataFrame 相当于一个二维表,相比 Series,DataFrame 的使用频率要高得多。我们先看看如何创建一个 DataFrame 对象:

import pandas as pd

# 创建一个 DataFrame 对象
df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1}
])
print(df['city'])

这段代码在上面我们已经演示过了。而在上面提到的统计函数,索引切片在 DataFrame 中也是有的,但是因为是二维的表,因此会有些不同。我们来详细看看,首先我们创建 DataFrame 可以指定行列索引:

import pandas as pd

df = pd.DataFrame([
    ['南昌', 2],
    ['武汉', -1]
], columns=['city', 'temperature'], index=[0, 1])

print(df)

输出效果如下:

  city  temperature
0   南昌            2
1   武汉           -1

和之前一样。另外我们可以查看一些属性:

import pandas as pd

df = pd.DataFrame([
    ['南昌', 2],
    ['武汉', -1]
], columns=['city', 'temperature'], index=[0, 1])

print(df.shape)
print(df.index)
print(df.columns)
print(df.values)
print(df.T)

输出结果如下:

(2, 2)
Int64Index([0, 1], dtype='int64')
Index(['city', 'temperature'], dtype='object')
[['南昌' 2]
 ['武汉' -1]]
              0   1
city         南昌  武汉
temperature   2  -1

前面几个很好理解,就是 df.T 看起来有点奇怪,不过仔细观察发现它就是原来的数据旋转 x、y 对换的结果,也就是转置。

下面我们来看看 DataFrame 的索引:

import pandas as pd

df = pd.DataFrame([
    ['南昌', 2],
    ['武汉', -1]
], columns=['city', 'temperature'], index=[0, 1])

print(df.loc[:, 'city'])
print(df.loc[:, 'city':'temperature'])

上面我们使用 loc 函数索引,它在 DataFrame 中的作用是按值索引。其中:

df.loc[:, 'city']

表示索引所有行的 city,而:

df.loc[:, 'city':'temperature']

表示索引所有行的 city 到 temperature。因为我的数据只有两列,所有输出结果如下:

0    南昌
1    武汉
Name: city, dtype: object
  city  temperature
0   南昌            2
1   武汉           -1

然后是用 iloc 函数进行下标索引:

import pandas as pd

df = pd.DataFrame([
    ['南昌', 2],
    ['武汉', -1]
], columns=['city', 'temperature'], index=[0, 1])

print(df.iloc[1:, :])
print(df.iloc[:, 1:])

含义是和 loc 差不多,只是 iloc 是通过数字下标进行索引,输出结果如下:

  city  temperature
1   武汉           -1
   temperature
0            2
1           -1

从 csv 文件读取数据

上面我们简单介绍了一下 Series 和 DataFrame 类型。在我们实际使用时,通常会选择从本地的 csv 文件获取 DataFrame 对象,下面我们来看看如何操作,先准备一个简单的 csv 文件:

city,temperature
南昌,2
武汉,-1

读取文件的代码如下:

import pandas as pd

df = pd.read_csv('test.csv')
print(df)

我们调用 read_csv 文件,然后传入文件路径。输出结果如下:

  city  temperature
0   南昌            2
1   武汉           -1

显示效果和之前是一样的。读取文件后,我们就可以对数据进行上面的操作了。当然,我们可以对数据修改后再保存到文件:

import pandas as pd
df = pd.read_csv('test.csv')
df = df.drop('city', axis=1)
df.to_csv('test.csv')

在读取文件后,我们调用了 drop 函数,删除 city 列,其中 axis 参数等于 1 表示删除列。然后调用 to_csv 保存到文件。

条件查询

我们还可以进行一些带条件的查询,我们使用一个新的 DataFrame 对象:

import pandas as pd

df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1},
    {'city': '上海', 'temperature': 1},
])
print(df[df['temperature'] > 0])

其中:

df[df['temperature'] > 0]

表示查询温度大于 0 度的数据。输出结果如下:

  city  temperature
0   南昌            2
2   上海            1

我们也可以指定多个条件:

import pandas as pd

df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1},
    {'city': '上海', 'temperature': 1},
])
print(df[(df['temperature'] > 0) & (df['temperature'] < 2)])

在上面代码中,我们查找了温度大于 0,且小于 2 的数据。这里需要注意一下

df['temperature'] > 0

会返回一个 bool 数组,我们可以用 df 索引这个数组,就是获取符合条件的数据。而多条件则是通过&或|连接。下面是代码的输出结果:

  city  temperature
2   上海            1

上面的操作叫做布尔索引,这个在 NumPy 中也有。除了通过布尔索引,我们还可以通过 query 方法实现:

import pandas as pd

df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1},
    {'city': '上海', 'temperature': 1},
])

print(df.query('temperature > 0'))

我们在 query 中传入条件,其中条件需要是字符串。下面是输出结果:

  city  temperature
0   南昌            2
2   上海            1

query 通用可以多条件索引,也是通过& 和 |来连接。

import pandas as pd

df = pd.DataFrame([
    {'city': '南昌', 'temperature': 2},
    {'city': '武汉', 'temperature': -1},
    {'city': '上海', 'temperature': 1},
])

print(df.query('temperature > 0 & temperature < 2'))

结果和上面的方式是一样的。