这里仅是对 pandas 入门学习的记录笔记,后续如果对某个函数或者对象需要深度学习的话,会另起文章详细介绍的。然后本文也是锻炼一下自己对英文文档的语感和阅读能力,欢迎直接查看官方文档学习,谢谢。
在 pd 中主要使用两种数据结构,一个是 DataFrame 2-D数据,一个是 Series 1-D数据,DataFrame 可以存储类似 SQL 的表字段数据。举例说明,我们可以通过字典创建一个 dataframe 对象,字典的键是 column,值是 column 下的 value 值。
import pandas as pd
df = pd.DataFrame(
{
"Name": [
"Braund, Mr. Owen Harris",
"Allen, Mr. William Henry",
"Bonnell, Miss. Elizabeth",
],
"Age": [22, 35, 58],
"Sex": ["male", "male", "female"],
}
)
print(df)
---
Name Age Sex
0 Braund, Mr. Owen Harris 22 male
1 Allen, Mr. William Henry 35 male
2 Bonnell, Miss. Elizabeth 58 female
在 DataFrame 和 Series 对象中,可以调用多种函数,例如 max() 、describe() 函数等等。
假设我们有一个 file.csv 的文件需要读取,pandas 提供了 read_csv() 方法读取,并返回一个 dataframe 对象。当我们打印输出该 df 对象会默认输出最先和最后分别的 5 条数据。
train_data = pd.read_csv(os.path.join(".","data","titanic_train.csv"))
print(train_data)
---
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
.. ... ... ... ... ... ... ...
886 887 0 2 ... 13.0000 NaN S
887 888 1 1 ... 30.0000 B42 S
888 889 0 3 ... 23.4500 NaN S
889 890 1 1 ... 30.0000 C148 C
890 891 0 3 ... 7.7500 NaN Q
当我们想输出前 n 行数据,可以使用 dataframe 对象的 head() 方法,同时传入我们的参数 n,类似的可以使用 tail() 方法返回末尾 n 条数据。
当我们想查看 df 对象每一列的数据类型,我们可以使用 dataframe 对象的 dtypes 属性,调用该属性会返回 df 对象每一列的数据类型。对于 df 对象的数据类型有 3 种类: integers (int64) 、floats (float64) and strings (object),我们可以清晰地看到在 df 中的字符串类型是 object 而不是 string,其实在 pandas 中字符串也可以是 string 类型。
这里需要注意的是,我们的对象的方法是需要有括号的,它代表着对对象执行的操作,例如 max() 方法等等。属性不需要括号,例如 dtypes 属性,它代表着获取对象的某种或某些特性。
对于 df 对象,如果我们想查看该对象的一些技术性信息,可以调用 info() 方法。我们需要注意的是,这个方法返回的信息在这里大致介绍下:
print(train_data.info())
---
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
None
总结:不同后缀的文件可以使用不同的读取函数 read_* 方法,在我们读取到的 df 对象可以使用 to_* 方法存储为不同类型的文件。获得到 df 对象后。我们可以使用 head/tail/info 方法或者 dtypes 属性检查 df 对象。
第一种情况,获取单列。我们还是读取 Titanic 数据集,获取 Age 列数据。可见,df 的单列是一个 Series 对象,s 对象的形状是一个一维向量。
>>> ageData = train["Age"]
>>> ageData.head()
0 22.0
1 38.0
2 26.0
3 35.0
4 35.0
Name: Age, dtype: float64
>>> ageData.shape
(891,)
>>> type(ageData)
<class 'pandas.core.series.Series'>
第二种情况,获取多列。假设我们想获取 Age 和 Sex 列,我们获得的是一个 DataFrame 对象。在这里解释一下,最外层 [] 代表我们获取元素的标志,如果我们获取多列,则需要传入一个列表 [] ,列表内存放列名标签。
>>> AgeSex = train[["Age", "Sex"]]
>>> AgeSex.head()
Age Sex
0 22.0 male
1 38.0 female
2 26.0 female
3 35.0 female
4 35.0 male
>>> type(AgeSex)
<class 'pandas.core.frame.DataFrame'>
>>> AgeSex.shape
(891, 2)
第三种情况,获取特定行。
假设一,我们想获取乘客年龄超过 35 岁的特定行,可以如下写代码。根据某列的条件,返回了 pandas DataFrame 对象,实现了获取特定行的要求。
>>> ageMore35 = train[train["Age"] > 35]
>>> ageMore35.head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
6 7 0 1 McCarthy, Mr. Timothy J male 54.0 0 0 17463 51.8625 E46 S
11 12 1 1 Bonnell, Miss. Elizabeth female 58.0 0 0 113783 26.5500 C103 S
13 14 0 3 Andersson, Mr. Anders Johan male 39.0 1 5 347082 31.2750 NaN S
15 16 1 2 Hewlett, Mrs. (Mary D Kingcome) female 55.0 0 0 248706 16.0000 NaN S
>>> ageMore35.shape
(217, 12)
>>> type(ageMore35)
<class 'pandas.core.frame.DataFrame'>
我们可以看一下 train[“Age”] > 35 返回了一个什么东东?可见,data 是一个 pandas Series 类型的对象,数据类型是 bool,行数和 train 数据集保持一致,train 数据集可以根据 index 的 true or false 选取为 true 的行返回。
>>> data = train["Age"] > 35
>>> type(data)
<class 'pandas.core.series.Series'>
>>> data.head()
0 False
1 True
2 False
3 False
4 False
Name: Age, dtype: bool
>>> data.shape
(891,)
假设二、对一个枚举类型的字段,我们该怎么处理呢?例如我们想获取船舱等级为 2 或 3 的乘客数据。这里用到了 isin 方法构成的一个条件表达式,如果某一行的 value 值在列表参数内,则返回 True。我们可以将这个条件表达式和上面的假设一一样之间放在选择括号 [] 内。
>>> class_23 = train[train["Pclass"].isin([2, 3])]
>>> class_23.head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
5 6 0 3 Moran, Mr. James male NaN 0 0 330877 8.4583 NaN Q
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S
第三种情况的延申,假设我们想通过两个条件实现对特定行数据的选取,我们该怎么做呢?也就是,我们关心 Age > 35 且 Pclass 在 2 和 3之间的乘客数据,我们可以把两个条件使用逻辑符号进行连接,例如与关系是 &,或关系是 |,而且每一个条件需要使用括号进行囊括。
>>> combine = train[(train["Age"] > 35) & (train["Pclass"].isin([2, 3]))]
>>> combine
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
13 14 0 3 Andersson, Mr. Anders Johan male 39.0 1 5 347082 31.2750 NaN S
15 16 1 2 Hewlett, Mrs. (Mary D Kingcome) female 55.0 0 0 248706 16.0000 NaN S
25 26 1 3 Asplund, Mrs. Carl Oscar (Selma Augusta Emilia... female 38.0 1 5 347077 31.3875 NaN S
33 34 0 2 Wheadon, Mr. Edward H male 66.0 0 0 C.A. 24579 10.5000 NaN S
40 41 0 3 Ahlin, Mrs. Johan (Johanna Persdotter Larsson) female 40.0 1 0 7546 9.4750 NaN S
.. ... ... ... ... ... ... ... ... ... ... ... ...
854 855 0 2 Carter, Mrs. Ernest Courtenay (Lilian Hughes) female 44.0 1 0 244252 26.0000 NaN S
860 861 0 3 Hansen, Mr. Claus Peter male 41.0 2 0 350026 14.1083 NaN S
865 866 1 2 Bystrom, Mrs. (Karolina) female 42.0 0 0 236852 13.0000 NaN S
873 874 0 3 Vander Cruyssen, Mr. Victor male 47.0 0 0 345765 9.0000 NaN S
885 886 0 3 Rice, Mrs. William (Margaret Norton) female 39.0 0 5 382652 29.1250 NaN Q
[113 rows x 12 columns]
第四种情况,获取缺失值。假设我们想获取所有缺失 Age 值的乘客数据,我们可以如下:
>>> train[train["Age"].isna()].head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
5 6 0 3 Moran, Mr. James male NaN 0 0 330877 8.4583 NaN Q
17 18 1 2 Williams, Mr. Charles Eugene male NaN 0 0 244373 13.0000 NaN S
19 20 1 3 Masselmani, Mrs. Fatima female NaN 0 0 2649 7.2250 NaN C
26 27 0 3 Emir, Mr. Farred Chehab male NaN 0 0 2631 7.2250 NaN C
28 29 1 3 O'Dwyer, Miss. Ellen "Nellie" female NaN 0 0 330959 7.8792 NaN Q
>>> train[train["Age"].isna()].shape
(177, 12)
那么获取非缺失值呢?可以使用 notna() 方法。
>>> train[train["Age"].notna()].head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
>>> train[train["Age"].notna()].shape
(714, 12)
当我们既对行有筛选,又对列有筛选的话,我们该怎么做呢?这时候仅仅的 [] 选择符是不够的,我们需要使用 iloc/loc 操作符在 [] 之前。当使用 loc/iloc 时,逗号之前的部分是想要的行,逗号之后的部分是想要选择的列。当使用列名、行标签或条件表达式时我们使用 loc 操作符。
>>> adult_names = train.loc[train["Age"]>35, ["Name","Sex"]]
>>> adult_names.head()
Name Sex
1 Cumings, Mrs. John Bradley (Florence Briggs Th... female
6 McCarthy, Mr. Timothy J male
11 Bonnell, Miss. Elizabeth female
13 Andersson, Mr. Anders Johan male
15 Hewlett, Mrs. (Mary D Kingcome) female
当根据表中的位置对某些行或列特别感兴趣时,可以在 [] 前使用iloc操作符。
>>> train.iloc[9:25, 2:5]