推荐:使用NSDT场景编辑器快速搭建3D应用场景
如果您正在从事数据科学项目,Python 包将简化您的生活,因为您只需要几行代码即可执行复杂的操作,例如操作数据和应用机器学习/深度学习模型。
在开始你的数据科学之旅时,建议从学习两个最有用的Python包开始:NumPy和Pandas。在本文中,我们将介绍这两个库。让我们开始吧!
什么是NumPy?
NumPy代表Numeric Python,用于在机器学习模型的幕后对数组和矩阵进行有效的计算。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 的数组开始。如果我们不确定数组的形状,有属性形状可以帮助我们:
a1 = np.array([[1,2,3],[4,5,6]]) print(a1) print('Shape of Array: ',a1.shape)
[[1 2 3] [4 5 6]] Shape of Array: (2, 3)
要将数组重塑为 3X2 维度,我们可以简单地使用函数 reshape:
a1 = a1.reshape(3,2) print(a1) print('Shape of Array: ',a1.shape)
[[1 2] [3 4] [5 6]] Shape of Array: (3, 2)
另一种常见的情况是将多维数组转换为单维数组。这可以通过将 -1 指定为形状来实现:
a1 = a1.reshape(-1) print(a1) print('Shape of Array: ',a1.shape)
[1 2 3 4 5 6] Shape of Array: (6,)
也可能需要获取转置数组:
a1 = np.array([[1,2,3,4,5,6]]) print('Before shape of Array: ',a1.shape) a1 = a1.T print(a1) print('After shape of Array: ',a1.shape)
Before shape of Array: (1, 6) [[1] [2] [3] [4] [5] [6]] After shape of Array: (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('Shape of Array a1: ',a1.shape) print('Shape of Array a2: ',a2.shape) a3 = np.matmul(a1,a2) # a3 = a1 @ a2 print(a3) print('Shape of Array a3: ',a3.shape)
Shape of Array a1: (2, 3) Shape of Array a2: (3, 2) [[30 36] [66 81]] Shape of Array 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('Shape of Array a3: ',a3.shape)
[[ 2 4 6] [ 8 10 12]] Shape of Array 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之上,对于操作数据集很有用。有两种主要的数据结构:系列和数据帧。序列是一系列值,而数据帧是包含行和列的表。换句话说,序列是数据帧的一列。
创建系列和数据帧
要构建序列,我们只需将值列表传递给方法:
import pandas as pd type_house = pd.Series(['Loft','Villa']) type_house
0 Loft 1 Villa dtype: object
我们可以通过传递对象字典来创建数据帧,其中键对应于列名,值是列的条目:
df = pd.DataFrame({'Price': [100000, 300000], 'date_construction': [1960, 2010]}) df.head()
创建数据帧后,我们可以检查每列的类型:
type(df.Price),type(df.date_construction)
(pandas.core.series.Series, pandas.core.series.Series)
应该清楚的是,列是系列类型的数据结构。
汇总函数
从现在开始,我们将通过使用Kaggle上提供的自行车共享数据集来展示Pandas的潜力。我们可以通过以下方式导入 CSV 文件:
df = pd.read_csv('/kaggle/input/bike-sharing-demand/train.csv') df.head()
Pandas不仅允许读取CSV文件,还允许读取Excel文件,JSON,Parquet和其他类型的文件。您可以在此处找到完整列表。
从输出中,我们可以可视化数据帧的前五行。如果我们想显示数据集的最后四行,我们使用 tail() 方法:
df.tail(4)
很少的行不足以很好地了解我们拥有的数据。开始分析的一个好方法是查看数据集的形状:
df.shape #(10886, 12)
我们有 10886 行和 12 列。是否要查看列名?这样做非常直观:
df.columns
有一种方法可以将所有这些信息可视化为唯一的输出:
df.info()
如果我们想显示每列的统计信息,可以使用 describe 方法:
df.describe()
从分类字段中提取信息也很重要。我们可以找到季节列的唯一值和唯一值的数量:
df.season.unique(),df.season.nunique()
输出:
(array([1, 2, 3, 4]), 4)
我们可以看到值为 1、2、3、4。然后,有四个可能的值。这种验证对于理解分类变量和防止色谱柱中包含的可能噪声至关重要。
要显示每个级别的频率,我们可以使用 value_counts() 方法:
df.season.value_counts()
最后一步应该是检查每列上的缺失值:
df.isnull().sum()
幸运的是,我们在这些字段中没有任何缺失值。
索引和切片
与在 Numpy 中一样,有基于索引的选择来从数据结构中选择数据。有两种主要方法可以从数据帧中获取条目:
- ILOC 根据整数位置选择元素
- LOC 根据标签或布尔数组获取项目。
要选择第一行,iloc 是最佳选择:
df.iloc[0]
如果我们想选择所有行,只选择第二列,我们可以执行以下操作:
df.iloc[:,1]
也可以同时选择更多列:
df.iloc[0:3,[0,1,2,5]]
根据索引选择列变得很复杂。最好指定列名。这可以使用 loc:
df.loc[0:3,['datetime','season','holiday','temp']]
与 Numpy 类似,可以根据条件过滤数据帧。例如,我们要返回天气等于 1 的所有行:
df[df.weather==1]
如果我们想返回包含特定列的输出,我们可以使用 loc:
df.loc[df.weather==1,['season','holiday']]
创建新变量
新变量的创建对从数据中提取更多信息和提高可解释性具有巨大影响。我们可以根据工作日的值创建一个新的分类变量:
df['workingday_c'] = df['workingday'].apply(lambda x: 'work' if x==1 else 'relax') df[['workingday','workingday_c']].head()
如果有多个条件,最好使用字典和方法映射来映射值:
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()
分组和排序
您可能希望根据分类列对数据进行分组。这可以使用分组方式:
df.groupby('season_c').agg({'count':['median','max']})
对于季节的每个级别,我们都可以观察到租用自行车的中位数和最大值。如果不根据列进行排序,此输出可能会令人困惑。我们可以使用 sort_values() 方法做到这一点:
df.groupby('season_c').agg({'count':['median','max']}).reset_index().sort_values(by=('count', 'median'),ascending=False)
现在,输出更有意义。我们可以推断,租用自行车数量最多的是夏季,而冬季则不是租用自行车的好月份。
结语
就是这样!我希望您发现本指南对学习NumPy和Pandas的基础知识很有用。它们通常是分开研究的,但首先了解NumPy,然后理解Pandas,这是建立在NumPy之上的,这可能是有见地的。
当然,有些方法我没有在本教程中介绍,但目标是介绍这两个库中最重要和最流行的方法。代码可以在Kaggle上找到。感谢您的阅读!有好的一天!
原文链接:https://www.mvrlink.com/introduction-to-numpy-and-pandas/