diff --git "a/Day66-70/67.NumPy\347\232\204\345\272\224\347\224\250.md" "b/Day66-70/67.NumPy\347\232\204\345\272\224\347\224\250.md" index db7d30ada85e22ff86cffc07e91d5d395c709cd2..1d363f5d126a71aafea5a3edb45597c80d89aba6 100644 --- "a/Day66-70/67.NumPy\347\232\204\345\272\224\347\224\250.md" +++ "b/Day66-70/67.NumPy\347\232\204\345\272\224\347\224\250.md" @@ -1430,4 +1430,5 @@ np.linalg.solve(a, b) ``` array([2., 3.]) -``` \ No newline at end of file +``` + diff --git "a/Day66-70/68.Pandas\347\232\204\345\272\224\347\224\250.md" "b/Day66-70/68.Pandas\347\232\204\345\272\224\347\224\250.md" index 3f8402586aa462244c17533f9f98f28110391a18..a116eeecc8cb3fc7dd15625fd6090810f19f9b1f 100644 --- "a/Day66-70/68.Pandas\347\232\204\345\272\224\347\224\250.md" +++ "b/Day66-70/68.Pandas\347\232\204\345\272\224\347\224\250.md" @@ -80,7 +80,7 @@ Pandas库中的`Series`对象可以用来表示一维数据结构,跟数组非 > **提示**:如果要使用负向索引,必须在创建`Series`对象时通过`index`属性指定非数值类型的标签。 -- 使用自己设置的标签索引 +- 使用自定义的标签索引 代码: @@ -199,7 +199,9 @@ Series对象的常用属性如下表所示。 `Series`对象的方法很多,我们通过下面的代码为大家介绍一些常用的方法。 -- 统计相关方法 +- 统计相关的方法 + + `Series`对象支持各种获取描述性统计信息的方法。 代码: @@ -257,9 +259,9 @@ Series对象的常用属性如下表所示。 dtype: float64 ``` - > **提示**:因为`describe()`返回的也是一个`Series`对象,所以可以用`ser2.describe()['mean']`来获取平均值。 + > **提示**:因为`describe()`返回的也是一个`Series`对象,所以也可以用`ser2.describe()['mean']`来获取平均值。 - 如果`Series`对象的数据中有重复元素,我们可以使用`unique()`方法获得去重之后的`Series`对象,如果想要统计重复元素重复的次数,可以使用`value_counts()`方法,这个方法会返回一个`Series`对象,它的索引就是原来的`Series`对象中的元素,而每个元素出现的次数就是返回的`Series`对象中的数据,在默认情况下会按照元素出现次数做降序排列。 + 如果`Series`对象有重复的值,我们可以使用`unique()`方法获得去重之后的`Series`对象;如果想要统计每个值重复的次数,可以使用`value_counts()`方法,这个方法会返回一个`Series`对象,它的索引就是原来的`Series`对象中的值,而每个值出现的次数就是返回的`Series`对象中的数据,在默认情况下会按照出现次数做降序排列。 代码: @@ -278,76 +280,76 @@ Series对象的常用属性如下表所示。 dtype: int64 ``` -- 数据处理方法 +- 数据处理的方法 `Series`对象的`dropna`和`fillna`方法分别用来删除空值和填充空值,具体的用法如下所示。 代码: - + ```Python ser4 = pd.Series(data=[10, 20, np.NaN, 30, np.NaN]) -ser4.dropna() + ser4.dropna() ``` 输出: - + ``` 0 10.0 1 20.0 3 30.0 -dtype: float64 + dtype: float64 ``` 代码: - + ```Python # 将空值填充为40 -ser4.fillna(value=40) + ser4.fillna(value=40) ``` 输出: - + ``` 0 10.0 1 20.0 2 40.0 3 30.0 4 40.0 -dtype: float64 + dtype: float64 ``` 代码: - + ```Python # backfill或bfill表示用后一个元素的值填充空值 # ffill或pad表示用前一个元素的值填充空值 -ser4.fillna(method='ffill') + ser4.fillna(method='ffill') ``` 输出: - + ``` 0 10.0 1 20.0 2 20.0 3 30.0 4 30.0 -dtype: float64 + dtype: float64 ``` - + 需要提醒大家注意的是,`dropna`和`fillna`方法都有一个名为`inplace`的参数,它的默认值是`False`,表示删除空值或填充空值不会修改原来的`Series`对象,而是返回一个新的`Series`对象来表示删除或填充空值后的数据系列,如果将`inplace`参数的值修改为`True`,那么删除或填充空值会就地操作,直接修改原来的`Series`对象,那么方法的返回值是`None`。后面我们会接触到的很多方法,包括`DataFrame`对象的很多方法都会有这个参数,它们的意义跟这里是一样的。 - + `Series`对象的`mask`和`where`方法可以将满足或不满足条件的值进行替换,如下所示。 - + 代码: - + ```Python ser5 = pd.Series(range(5)) ser5.where(ser5 > 0) ``` - + 输出: - + ``` 0 NaN 1 1.0 @@ -356,15 +358,15 @@ dtype: float64 4 4.0 dtype: float64 ``` - + 代码: - + ```Python ser5.where(ser5 > 1, 10) ``` - + 输出: - + ``` 0 10 1 10 @@ -373,15 +375,15 @@ dtype: float64 4 4 dtype: int64 ``` - + 代码: - + ```Python ser5.mask(ser5 > 1, 10) ``` - + 输出: - + ``` 0 0 1 1 @@ -390,18 +392,18 @@ dtype: float64 4 10 dtype: int64 ``` - - `Series`对象的`apply`和`map`方法可以用于对数据进行处理,代码如下所示。 - + + `Series`对象的`apply`和`map`方法非常重要,它们可以用于数据处理,把数据映射或转换成我们期望的样子,这个操作在数据分析的数据准备阶段非常重要。 + 代码: - + ```Python ser6 = pd.Series(['cat', 'dog', np.nan, 'rabbit']) ser6 ``` - + 输出: - + ``` 0 cat 1 dog @@ -409,15 +411,15 @@ dtype: float64 3 rabbit dtype: object ``` - + 代码: - + ```Python ser6.map({'cat': 'kitten', 'dog': 'puppy'}) ``` - + 输出: - + ``` 0 kitten 1 puppy @@ -425,15 +427,15 @@ dtype: float64 3 NaN dtype: object ``` - + 代码: - + ```Python ser6.map('I am a {}'.format, na_action='ignore') ``` - + 输出: - + ``` 0 I am a cat 1 I am a dog @@ -441,54 +443,131 @@ dtype: float64 3 I am a rabbit dtype: object ``` - + 代码: - + ```Python ser7 = pd.Series([20, 21, 12], index=['London', 'New York', 'Helsinki']) ser7 ``` - + 输出: - + ``` London 20 New York 21 Helsinki 12 dtype: int64 ``` - + 代码: - + ```Python ser7.apply(np.square) ``` - + 输出: - + ``` London 400 New York 441 Helsinki 144 dtype: int64 ``` - + 代码: - + ```Python ser7.apply(lambda x, value: x - value, args=(5, )) ``` - + 输出: - + ``` London 15 New York 16 Helsinki 7 dtype: int64 ``` + +- 排序和取头部值的方法 + + `Series`对象的`sort_index`和`sort_values`方法可以用于对索引和数据的排序,排序方法有一个名为`ascending`的布尔类型参数,该参数用于控制排序的结果是升序还是降序;而名为`kind`的参数则用来控制排序使用的算法,默认使用了`quicksort`,也可以选择`mergesort`或`heapsort`;如果存在空值,那么可以用`na_position`参数空值放在最前还是最后,默认是`last`,代码如下所示。 + + 代码: + + ```Python +ser8 = pd.Series( + data=[35, 96, 12, 57, 25, 89], + index=['grape', 'banana', 'pitaya', 'apple', 'peach', 'orange'] + ) + # 按值从小到大排序 + ser8.sort_values() + ``` + + 输出: + + ``` + pitaya 12 + peach 25 + grape 35 + apple 57 + orange 89 + banana 96 + dtype: int64 + ``` + + 代码: + + ```Python + # 按索引从大到小排序 + ser8.sort_index(ascending=False) + ``` + + 输出: + + ``` + pitaya 12 + peach 25 + orange 89 + grape 35 + banana 96 + apple 57 + dtype: int64 + ``` + + 如果要从`Series`对象中找出元素中最大或最小的“Top-N”,实际上是不需要对所有的值进行排序的,可以使用`nlargest`和`nsmallest`方法来完成,如下所示。 - `Series`对象的`sort_index`和`sort_values`方法可以用于对索引和数据的排序,排序方法有一个名为`ascending`的布尔类型参数,该参数用于控制排序的结果是升序还是降序;而名为`kind`的参数则用来控制排序使用的算法,默认使用了`quicksort`,也可以选择`mergesort`或`heapsort`;如果存在空值,那么可以用`na_position`参数空值放在最前还是最后,默认是`last`。 + 代码: + + ```Python + # 值最大的3个 + ser8.nlargest(3) + ``` + + 输出: + + ``` + banana 96 + orange 89 + apple 57 + dtype: int64 + ``` + + 代码: + + ```Python + # 值最小的2个 + ser8.nsmallest(2) + ``` + + 输出: + + ``` + pitaya 12 + peach 25 + dtype: int64 + ``` #### 绘制图表 @@ -508,14 +587,14 @@ plt.rcParams['axes.unicode_minus'] = False 创建`Series`对象并绘制对应的柱状图。 ```Python -ser8 = pd.Series({'一季度': 400, '二季度': 520, '三季度': 180, '四季度': 380}) +ser9 = pd.Series({'一季度': 400, '二季度': 520, '三季度': 180, '四季度': 380}) # 通过Series对象的plot方法绘图(kind='bar'表示绘制柱状图) -ser8.plot(kind='bar', color=['r', 'g', 'b', 'y']) +ser9.plot(kind='bar', color=['r', 'g', 'b', 'y']) # x轴的坐标旋转到0度(中文水平显示) plt.xticks(rotation=0) # 在柱状图的柱子上绘制数字 for i in range(4): - plt.text(i, ser8[i] + 5, ser8[i], ha='center') + plt.text(i, ser9[i] + 5, ser9[i], ha='center') # 显示图像 plt.show() ``` @@ -526,7 +605,7 @@ plt.show() ```Python # autopct参数可以配置在饼图上显示每块饼的占比 -ser8.plot(kind='pie', autopct='%.1f%%') +ser9.plot(kind='pie', autopct='%.1f%%') # 设置y轴的标签(显示在饼图左侧的文字) plt.ylabel('各季度占比') plt.show() @@ -538,11 +617,196 @@ plt.show() #### 创建DataFrame对象 +1. 通过二维数组创建`DataFrame`对象。 + + 代码: + + ```Python + scores = np.random.randint(60, 101, (5, 3)) + courses = ['语文', '数学', '英语'] + ids = [1001, 1002, 1003, 1004, 1005] + df1 = pd.DataFrame(data=scores, columns=courses, index=ids) + df1 + ``` + + 输出: + + ``` + 语文 数学 英语 + 1001 69 80 79 + 1002 71 60 100 + 1003 94 81 93 + 1004 88 88 67 + 1005 82 66 60 + ``` + +2. 通过字典创建`DataFrame`对象。 + + 代码: + + ```Python + scores = { + '语文': [62, 72, 93, 88, 93], + '数学': [95, 65, 86, 66, 87], + '英语': [66, 75, 82, 69, 82], + } + ids = [1001, 1002, 1003, 1004, 1005] + df2 = pd.DataFrame(data=scores, index=ids) + df2 + ``` + + 输出: + + ``` + 语文 数学 英语 + 1001 69 80 79 + 1002 71 60 100 + 1003 94 81 93 + 1004 88 88 67 + 1005 82 66 60 + ``` + +3. 读取CSV文件创建`DataFrame`对象。 + + 可以通过`pandas` 模块的`read_csv`函数来读取CSV文件,`read_csv`函数的参数非常多,下面接受几个比较重要的参数。 + + - `sep` / `delimiter`:分隔符,默认是`,`。 + - `header`:表头(列索引)的位置,默认值是`infer`,用第一行的内容作为表头(列索引)。 + - `index_col`:用作行索引(标签)的列。 + - `usecols`:需要加载的列,可以使用序号或者列名。 + - `true_values` / `false_values`:哪些值被视为布尔值`True` / `False`。 + - `skiprows`:通过行号、索引或函数指定需要跳过的行。 + - `skipfooter`:要跳过的末尾行数。 + - `nrows`:需要读取的行数。 + - `na_values`:哪些值被视为空值。 + + 代码: + + ```Python + df3 = pd.read_csv('2018年北京积分落户数据.csv', index_col='id') + df3 + ``` + 输出: + + ``` + name birthday company score + id + 1 杨效丰 1972-12 北京利德华福电气技术有限公司 122.59 + 2 纪丰伟 1974-12 北京航天数据股份有限公司 121.25 + 3 王永 1974-05 品牌联盟(北京)咨询股份公司 118.96 + 4 杨静 1975-07 中科专利商标代理有限责任公司 118.21 + 5 张凯江 1974-11 北京阿里巴巴云计算技术有限公司 117.79 + ... ... ... ... ... + 6015 孙宏波 1978-08 华为海洋网络有限公司北京科技分公司 90.75 + 6016 刘丽香 1976-11 福斯(上海)流体设备有限公司北京分公司 90.75 + 6017 周崧 1977-10 赢创德固赛(中国)投资有限公司 90.75 + 6018 赵妍 1979-07 澳科利耳医疗器械(北京)有限公司 90.75 + 6019 贺锐 1981-06 北京宝洁技术有限公司 90.75 + 6019 rows × 4 columns + ``` + + > **说明**:如果需要上面例子中的CSV文件,可以通过下面的百度云盘地址进行获取。 + > + > 链接:https://pan.baidu.com/s/1rQujl5RQn9R7PadB2Z5g_g,提取码:e7b4。 + +4. 读取Excel文件创建`DataFrame`对象。 + + 可以通过`pandas` 模块的`read_excel`函数来读取Excel文件,该函数与上面的`read_csv`非常相近,多了一个`sheet_name`参数来指定数据表的名称,但是不同于CSV文件,没有`sep`或`delimiter`这样的参数。 + + 代码: + + ```Python + import random + + # 读取Excel文件并随机获取其中约5%的数据 + df4 = pd.read_excel( + io='某视频网站运营数据.xlsx', + skiprows=lambda x: x > 0 and random.random() > 0.05 + ) + ``` + +5. 通过SQL从数据库读取数据创建`DataFrame`对象。 + + 代码: + + ```Python + import pymysql + + # 创建一个MySQL数据库的连接对象 + conn = pymysql.connect( + host='47.104.31.138', port=3306, user='guest', + password='Guest.618', database='hrs', charset='utf8mb4' + ) + # 通过SQL从数据库读取数据创建DataFrame + df5 = pd.read_sql('select * from tb_emp', conn, index_col='eno') + df5 + ``` + + > **提示**:执行上面的代码需要先安装`pymysql`库,如果尚未安装,可以先在Notebook的单元格中先执行`!pip install pymysql`,然后再运行上面的代码。上面的代码连接的是我部署在阿里云上的MySQL数据库,公网IP地址:`47.104.31.138`,用户名:`guest`,密码:`Guest.618`。 + + 输出: + + ``` + ename job mgr sal comm dno + eno + 1359 胡一刀 销售员 3344 1800 200 30 + 2056 乔峰 分析师 7800 5000 1500 20 + 3088 李莫愁 设计师 2056 3500 800 20 + 3211 张无忌 程序员 2056 3200 NaN 20 + 3233 丘处机 程序员 2056 3400 NaN 20 + 3244 欧阳锋 程序员 3088 3200 NaN 20 + 3251 张翠山 程序员 2056 4000 NaN 20 + 3344 黄蓉 销售主管 7800 3000 800 30 + 3577 杨过 会计 5566 2200 NaN 10 + 3588 朱九真 会计 5566 2500 NaN 10 + 4466 苗人凤 销售员 3344 2500 NaN 30 + 5234 郭靖 出纳 5566 2000 NaN 10 + 5566 宋远桥 会计师 7800 4000 1000 10 + 7800 张三丰 总裁 NaN 9000 1200 20 + ``` #### 基本属性和方法 +`DataFrame`对象的属性如下表所示。 + +| 属性名 | 说明 | +| -------------- | ----------------------------------- | +| `at` / `iat` | 通过标签获取`DataFrame`中的单个值。 | +| `columns` | `DataFrame`对象列的索引 | +| `dtypes` | `DataFrame`对象每一列的数据类型 | +| `empty` | `DataFrame`对象是否为空 | +| `loc` / `iloc` | 通过标签获取`DataFrame`中的一组值。 | +| `ndim` | `DataFrame`对象的维度 | +| `shape` | `DataFrame`对象的形状(行数和列数) | +| `size` | `DataFrame`对象中元素的个数 | +| `values` | `DataFrame`对象的数据对应的二维数组 | + +关于`DataFrame`的方法,首先需要了解的是`info()`方法,它可以帮助我们了解`DataFrame`的相关信息,如下所示。 + +代码: +```Python +df5.info() +``` + +输出: + +``` + +Int64Index: 14 entries, 1359 to 7800 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 ename 14 non-null object + 1 job 14 non-null object + 2 mgr 13 non-null float64 + 3 sal 14 non-null int64 + 4 comm 6 non-null float64 + 5 dno 14 non-null int64 +dtypes: float64(2), int64(2), object(2) +memory usage: 1.3+ KB +``` #### 获取数据