Quellcode durchsuchen

更新了第67天和第68天文档

jackfrued vor 4 Jahren
Ursprung
Commit
d2c6ce9c46
2 geänderte Dateien mit 328 neuen und 63 gelöschten Zeilen
  1. 2 1
      Day66-70/67.NumPy的应用.md
  2. 326 62
      Day66-70/68.Pandas的应用.md

+ 2 - 1
Day66-70/67.NumPy的应用.md

@@ -1430,4 +1430,5 @@ np.linalg.solve(a, b)
 
 ```
 array([2., 3.])
-```
+```
+

+ 326 - 62
Day66-70/68.Pandas的应用.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()
+```
+
+输出:
+
+```
+<class 'pandas.core.frame.DataFrame'>
+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
+```
 
 #### 获取数据