Press "Enter" to skip to content

Numpy和Pandas简介

Numpy和Pandas简介 四海 第1张  

Python 是数据科学领域中最流行的语言,因其简单性、庞大的社区和大量的开源库而受到广泛使用。

如果你正在进行数据科学项目,Python 的包将会使你的工作变得更加轻松,因为你只需要几行代码就可以完成复杂的操作,如数据操作和应用机器学习/深度学习模型。

在开始你的数据科学之旅时,建议先学习两个最有用的 Python 包:NumPy 和 Pandas。本文将介绍这两个库。让我们开始吧!

 

NumPy 是什么?

 

NumPy 是 Numerical Python 的缩写,它用于在机器学习模型的背后进行高效的数组和矩阵计算。NumPy 的基本构建块是数组,它是一个类似于列表的数据结构,但提供了大量的数学函数。换句话说,NumPy 数组是一个多维数组对象。

 

创建 NumPy 数组

 

我们可以使用列表或列表的列表来定义 NumPy 数组:

import numpy as np
l = [[1,2,3],[4,5,6],[7,8,9]]
numpy_array = np.array(l)
numpy_array

 

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

 

与列表的列表不同,我们可以使用缩进来可视化 3X3 的矩阵。此外,NumPy 还提供了40多个内置函数用于创建数组。

要创建一个填充为零的数组,可以使用 np.zeros 函数,只需要指定所需的形状:

zeros_array = np.zeros((3,4))
zeros_array

 

array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

 

同样地,我们可以创建一个填充为 1 的数组:

ones_array = np.ones((3,4))
ones_array

 

array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])

 

我们还可以创建单位矩阵,它是一个主对角线上元素为 1,副对角线上元素为 0 的方阵:

identity_array = np.identity(3)
identity_array

 

array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

 

此外,NumPy 还提供了不同的函数来创建随机数组。要创建一个从均匀分布 [0,1] 中随机取样的数组,只需要使用函数 np.random.rand :

random_array = np.random.rand(3,4)
random_array

 

array([[0.84449279, 0.71146992, 0.48159787, 0.04927379],
       [0.03428534, 0.26851667, 0.65718662, 0.52284251],
       [0.1380207 , 0.91146148, 0.74171469, 0.57325424]])

 

与前一个函数类似,我们可以定义一个带有随机值的数组,但这次是从标准正态分布中取样:

randn_array = np.random.randn(10)
randn_array

 

array([-0.68398432, -0.25466784,  0.27020797,  0.29632334, -0.20064897,
        0.7988508 ,  1.34759319, -0.41418478, -0.35223377, -0.10282884])

 

如果我们有兴趣构建一个随机整数数组,这些整数属于区间[low,high),我们只需要使用np.random.randint函数:

randint_array = np.random.randint(1,20,20)
randint_array

 

array([14,  3,  1,  2, 17, 15,  5, 17, 18,  9,  4, 19, 14, 14,  1, 10, 17,
       19,  4,  6])

 

索引和切片

 

除了用于数组创建的内置函数之外,NumPy的另一个优点是可以使用一组方括号从数组中选择元素。例如,我们可以尝试获取矩阵的第一行:

a1 = np.array([[1,2,3],[4,5,6]])
a1[0]

 

array([1, 2, 3])

 

假设我们想选择第一行的第三个元素。在这种情况下,我们需要指定两个索引,即行索引和列索引:

print(a1[0,2]) #3

 

另一种选择是使用a1[0][2],但这被认为是低效的,因为它首先创建包含第一行的数组,然后从该行中选择元素。

此外,我们可以使用方括号内的语法start:stop:step从矩阵中取出切片,其中停止索引不包含在内。例如,我们再次想选择第一行,但只取前两个元素:

print(a1[0,0:2]) 

 

[1 2]

 

如果我们想选择所有行,但只提取每行的第一个元素:

print(a1[:,0])

 

[1 4]

 

除了整数数组索引之外,还有布尔数组索引来从数组中选择元素。假设我们只想选择满足以下条件的元素:

a1>5

 

array([[False, False, False],
       [False, False,  True]])

 

如果我们根据这个条件过滤数组,输出将只显示True元素:

a1[a1>5]

 

array([6])

 

数组操作

 

在进行数据科学项目时,经常需要将数组重新形状为新的形状而不改变数据。

例如,我们从一个维度为2X3的数组开始。如果我们不确定数组的形状,可以使用shape属性来帮助我们:

a1 = np.array([[1,2,3],[4,5,6]])
print(a1)
print('数组形状:',a1.shape)

 

[[1 2 3]
 [4 5 6]]
数组形状: (2, 3)

 

要将数组重新形状为3X2的维度,我们可以简单地使用reshape函数:

a1 = a1.reshape(3,2)
print(a1)
print('数组形状: ',a1.shape)

 

[[1 2]
 [3 4]
 [5 6]]
数组形状:  (3, 2)

 

另一个常见的情况是将多维数组转换为一维数组。可以通过指定-1作为形状来实现:

a1 = a1.reshape(-1)
print(a1)
print('数组形状: ',a1.shape)

 

[1 2 3 4 5 6]
数组形状:  (6,)

 

有时候需要获得转置后的数组:

a1 = np.array([[1,2,3,4,5,6]])
print('转置前数组形状: ',a1.shape)
a1 = a1.T
print(a1)
print('转置后数组形状: ',a1.shape)

 

转置前数组形状:  (1, 6)
[[1]
 [2]
 [3]
 [4]
 [5]
 [6]]
转置后数组形状:  (6, 1)

 

同样,也可以使用np.transpose(a1)来实现相同的转置。

 

数组乘法

 

如果要从头开始构建机器学习算法,你肯定需要计算两个数组的矩阵乘积。当数组维度大于1时,可以使用函数np.matmul来实现:

a1 = np.array([[1,2,3],[4,5,6]])
a2 = np.array([[1,2],[4,5],[7,8]])
print('数组a1的形状: ',a1.shape)
print('数组a2的形状: ',a2.shape)
a3 = np.matmul(a1,a2) 
# a3 = a1 @ a2
print(a3)
print('数组a3的形状: ',a3.shape)

 

数组a1的形状:  (2, 3)
数组a2的形状:  (3, 2)
[[30 36]
 [66 81]]
数组a3的形状:  (2, 2)

 

@可以作为np.matmul的简洁替代方式。

如果要将矩阵乘以标量,np.dot是最佳选择:

a1 = np.array([[1,2,3],[4,5,6]])
a3 = np.dot(a1,2)
# a3 = a1 * 2
print(a3)
print('数组a3的形状: ',a3.shape)

 

[[ 2  4  6]
 [ 8 10 12]]
数组a3的形状:  (2, 3)

 

在这种情况下,*可以作为np.dot的简洁替代方式。

 

数学函数

 

NumPy提供了大量的数学函数,例如三角函数、取整函数、指数函数、对数函数等等。你可以在这里找到完整列表。我们将展示一些最重要的函数,你可以应用到你的问题中。

指数函数和自然对数函数无疑是最常见和最常用的转换:

a1 = np.array([[1,2,3],[4,5,6]])
print(np.exp(a1))

 

[[  2.71828183   7.3890561   20.08553692]
 [ 54.59815003 148.4131591  403.42879349]]

 

a1 = np.array([[1,2,3],[4,5,6]])
print(np.log(a1))

 

[[0.         0.69314718 1.09861229]
 [1.38629436 1.60943791 1.79175947]]

 

如果我们想要在单行代码中提取最小值和最大值,我们只需要调用以下函数:

a1 = np.array([[1,2,3],[4,5,6]])
print(np.min(a1),np.max(a1))  # 1 6

 

我们还可以计算数组中每个元素的平方根:

a1 = np.array([[1,2,3],[4,5,6]])
print(np.sqrt(a1))

 

[[1.         1.41421356 1.73205081]
 [2.         2.23606798 2.44948974]]

 

什么是Pandas?

 

Pandas建立在Numpy上,用于操作数据集。主要有两种数据结构:SeriesDataframe。Series是一个值的序列,而Dataframe是一个带有行和列的表格。换句话说,Series是Dataframe的一列。

 

创建Series和Dataframe

 

要构建Series,我们只需将值列表传递给方法:

import pandas as pd
type_house = pd.Series(['Loft','Villa'])
type_house

 

0     Loft
1    Villa
dtype: object

 

我们可以通过传递对象字典来创建Dataframe,其中键对应于列名,值是列的条目:

df = pd.DataFrame({'Price': [100000, 300000], 'date_construction': [1960, 2010]})
df.head()

 

Numpy和Pandas简介 四海 第2张  

创建Dataframe后,我们可以检查每列的类型:

type(df.Price),type(df.date_construction)

 

(pandas.core.series.Series, pandas.core.series.Series)

 

很明显,列是Series类型的数据结构。

 

汇总函数

 

从现在开始,我们将使用Kaggle上提供的自行车共享数据集展示Pandas的潜力。我们可以以以下方式导入CSV文件:

df = pd.read_csv('/kaggle/input/bike-sharing-demand/train.csv')
df.head()

 

Numpy和Pandas简介 四海 第3张  

Pandas不仅允许读取CSV文件,还可以读取Excel文件、JSON、Parquet和其他类型的文件。您可以在这里找到完整列表。

从输出中,我们可以可视化数据框的前五行。如果我们想要显示数据集的最后四行,我们可以使用tail()方法:

df.tail(4)

 

Numpy和Pandas简介 四海 第4张  

几行数据不足以对我们拥有的数据有一个好的了解。开始分析的一个好方法是查看数据集的形状:

df.shape                    #(10886, 12)

 

我们有10886行和12列。您想要查看列名吗?这非常直观:

df.columns

 

Numpy和Pandas简介 四海 第5张  

有一种方法可以将所有这些信息可视化到一个输出中:

df.info()

 

Numpy和Pandas简介 四海 第6张  

如果我们想要显示每列的统计信息,可以使用describe方法:

df.describe()

 

Numpy和Pandas简介 四海 第6张  

从分类字段中提取信息也很重要。我们可以找到season列的唯一值和唯一值的数量:

df.season.unique(),df.season.nunique()

 

输出:

(array([1, 2, 3, 4]), 4)

 

我们可以看到值为1, 2, 3, 4。因此,有四个可能的值。这个验证对于理解分类变量并防止列中可能包含的噪声非常重要。

要显示每个级别的频率,可以使用value_counts()方法:

df.season.value_counts()

 

Numpy和Pandas简介 四海 第8张  

最后一步应该是检查每列中的缺失值:

df.isnull().sum()

 

Numpy和Pandas简介 四海 第9张  

幸运的是,在这些字段中我们没有任何缺失值。

 

索引和切片

 

与Numpy类似,有基于索引的选择来从数据结构中选择数据。从数据框中获取条目的主要方法有两种:

  • iloc基于整数位置选择元素
  • loc基于标签或布尔数组获取元素。

要选择第一行,iloc是最好的选择:

df.iloc[0]

 

Numpy和Pandas简介 四海 第10张  

如果我们想要选择所有行和第二列,可以这样做:

df.iloc[:,1]

 

Numpy和Pandas简介 四海 第11张  

也可以同时选择多列:

df.iloc[0:3,[0,1,2,5]]

 

Numpy和Pandas简介 四海 第12张  

根据索引选择列变得复杂。最好指定列名。可以使用loc来实现:

df.loc[0:3,['datetime','season','holiday','temp']]

 

Numpy和Pandas简介 四海 第13张  

与Numpy类似,可以根据条件过滤数据框。例如,我们想要返回所有weather等于1的行:

df[df.weather==1]

 

Numpy和Pandas简介 四海 第14张  

如果我们想要返回特定列的输出,可以使用loc:

df.loc[df.weather==1,['season','holiday']]

  Numpy和Pandas简介 四海 第15张

 

创建新变量

创建新变量对从数据中提取更多信息和提高可解释性有巨大影响。我们可以根据workingday的值创建一个新的分类变量:

df['workingday_c'] = df['workingday'].apply(lambda x: 'work' if x==1 else 'relax')
df[['workingday','workingday_c']].head()

Numpy和Pandas简介 四海 第16张

如果有多个条件,最好使用字典和map方法来映射值:

diz_season = {1:'winter',2:'spring',3:'summer',4:'fall'}
df['season_c'] = df['season'].map(lambda x: diz_season[x])
df[['season','season_c']].head()

Numpy和Pandas简介 四海 第17张

分组和排序

有时候你想要根据分类列对数据进行分组。可以使用groupby来实现:

df.groupby('season_c').agg({'count':['median','max']})

Numpy和Pandas简介 四海 第18张

对于每个季节的级别,我们可以观察到租赁自行车的中位数和最大值。如果不基于列进行排序,这个输出可能会令人困惑。我们可以使用sort_values()方法来排序:

df.groupby('season_c').agg({'count':['median','max']}).reset_index().sort_values(by=('count', 'median'),ascending=False)

Numpy和Pandas简介 四海 第19张

现在,输出更有意义了。我们可以推断出夏天租借自行车的数量最多,而冬天不是一个适合租借自行车的好月份。

最后的想法

就这些!希望您觉得这个指南对学习NumPy和Pandas的基础知识有用。它们通常是分开学习的,但先学习NumPy,然后再学习建立在NumPy之上的Pandas可能更有洞察力。

在教程中,肯定有我没有涵盖的方法,但目标是涵盖这两个库中最重要和最流行的方法。代码可以在Kaggle上找到。谢谢阅读!祝您有愉快的一天! Eugenia Anello目前是意大利帕多瓦大学信息工程系的研究员。她的研究项目专注于连续学习与异常检测的结合。

Leave a Reply

Your email address will not be published. Required fields are marked *