为了账号安全,请及时绑定邮箱和手机立即绑定
5.4 创建集合

>>> x = set()>>> x{}创建一个空的集合>>> iterable = ('a', 'b', 'c')>>> x = list(iterable)>>> x{'a', 'b', 'c'}创建一个可迭代对象 iterable,iterable 是一个包含 3 个元素的元组通过 set(iterable) 将可迭代对象 iterable 转换为 set

3.2 修改某区域数据值

我们还可以对某些行或列的数据进行统一的修改操作,这里我们可以使用函数 loc() 或 iloc() ,只是要注意传入的参数不同。下面我们使用 iloc() 修改整行或整列的数据操作:# 导入pandas包import pandas as pd# 指定导入的文件地址data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第7,8,9,10小节/execl数据demo.xlsx"# 解析数据data = pd.read_excel(data_path)print(data)# --- 输出结果 ---编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# 这里我们创建了一个新的数据集data_new= pd.DataFrame([["11","22","33.5","44"], ["55","66","77.7","88"]], columns=["编程语言","推出时间","价格","主要创始人"])data.iloc[[0,1]]=data_newprint(data)# --- 输出结果 ---编程语言 推出时间 价格 主要创始人0 11 22 33.5 441 55 66 77.7 882 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75 Bjarne Stroustrup输出解析:我们创建了一个新的数据集,用来替换原数据第1行和第2行的数据,通过输出结果可以看到被修改后的数据集。下面我们来修改一整列的数据:# 创建了一个Series对象new_series=pd.Series(["11","22","3","44","55","66"] )data.iloc[:,[1]]=new_seriesprint(data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 11 45.6 James Gosling1 python 22 67.0 Guido van Rossum2 C 3 33.9 Dennis MacAlistair Ritchie3 js 44 59.5 Brendan Eich4 php 55 69.9 Rasmus Lerdorf5 C++ 66 75.0 Bjarne Stroustrup输出解析:这里我们新建一个 Series 对象用来替换第二列的数据值,通过输出结果可以看到为我们第二列的数据值被修改的结果。

5.1 read_sql() 函数

该函数主要从数据库中读取数据帧,里面提供了一些参数可以设置,下面列举常用的几个参数:参数名称描述sql要执行的 sql 语句con数据库连接对象params参数的传递index_col选择某一列作为 index参数 sql 和参数 con我们首先通过代码演示这两个参数的设置,读取 example 数据库中的 t_file 数据表数据:# 导入pandas 和 pymysql 包import pandas as pdimport pymysql# 返回一个 Connection 对象db_conn = pymysql.connect(host='localhost',port=3306,user='root',password='0508',database='example',charset='utf8')# 执行sql操作sql="select * from t_file"pd.read_sql(sql,con=db_conn)# --- 输出结果 --- id directory fileName md5 size time type0 1 C:/temp-rainy1 汇报.png 845a500eca6ef877 22507 2020-01-16 10:53:02 png1 2 C:/temp-rainy2 模板.png 845a500eca6ef877 22507 2020-01-16 10:59:16 png2 3 C:/temp-rainy3 说明书.docx 5626d69f9f39d65d 235999 2020-01-16 10:59:45 docx3 4 C:/temp-rainy4 接口及调用说明.rar 459e008250ccb9ca1 391542 2020-01-16 11:02:07 rar4 5 C:/temp-rainy5 数据说明.pdf 333052beda8773 434439 2020-01-16 13:44:03 pdf输出解析:我们通过 sql 语句设置数据库操作语句,这里我们是查询 t_file 的所有数据,参数 con 中我们传入了 PyMySQL 库创建的 db_con 数据库连接对象。通过输出结果可以看到,查出了 t_file 中的数据内容。参数 params该参数用于我们执行 sql 中参数的配置:# 导入pandas 和 pymysql 包import pandas as pdimport pymysql# 返回一个 Connection 对象db_conn = pymysql.connect(host='localhost',port=3306,user='root',password='0508',database='example',charset='utf8')# 执行sql操作sql = "select * from t_file where id = %s"pd.read_sql(sql,con=db_conn,params=[2])# --- 输出结果 --- id directory fileName md5 size time type0 2 C:/temp-rainy2 模板.png 845a500eca6ef877 22507 2020-01-16 10:59:16 png输出解析:我们 sql 查询语句中设置了 id 的参数条件,在 read_sql() 函数中我们通过 params 参数设置了 id 的条件为 2,因此看到我们的数据结果,正是我们数据库中 id=2 的数据行。参数 index_col通过该参数的设置,某一列指定为行索引。# 导入pandas 和 pymysql 包import pandas as pdimport pymysql# 返回一个 Connection 对象db_conn = pymysql.connect(host='localhost',port=3306,user='root',password='0508',database='example',charset='utf8')# 执行sql操作sql = "select * from t_file"pd.read_sql(sql,con=db_conn,index_col="type")# --- 输出结果 --- id directory fileName md5 size timetype png 1 C:/temp-rainy1 汇报.png 845a500eca6ef877 22507 2020-01-16 10:53:02png 2 C:/temp-rainy2 模板.png 845a500eca6ef877 22507 2020-01-16 10:59:16docx 3 C:/temp-rainy3 说明书.docx 5626d69f9f39d65d 235999 2020-01-16 10:59:45rar 4 C:/temp-rainy4 接口及调用说明.rar 459e008250ccb9ca1 391542 2020-01-16 11:02:07pdf 5 C:/temp-rainy5 数据说明.pdf 333052beda8773 434439 2020-01-16 13:44:03输出解析:程序中我们通过设置 index_col=“type” ,指定字段文件的类型 (type) 作为我们数据行的索引,这里可以看到输出结果,最左侧的一列正式我们的 type 数据列,如果不指定 index_col ,默认的行索引是从0开始进行序号递增编排。

2.1 删除指定的行

# 导入pandas包import pandas as pd# 指定导入的文件地址data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第7,8,9,10小节/execl数据demo.xlsx"# 解析数据data = pd.read_excel(data_path)print(data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# 删除指定行 等价于drop(labels=[0,1],axis=0)data_res=data.drop(labels=[1,3])print(data_res)print(data)# --- 输出结果 ---# --- data_res的数据集 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling2 C 1972年 33.9 Dennis MacAlistair Ritchie4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# --- data的数据集 ---- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup输出解析:我们通过 drop() 方法的 labels 设置了标签为 1 和 3,默认是 axis=0 则对应的是删除行索引为 1 和 3 的行数据,如果 axis=0 是删除行数据而设置的 labels 对应的不是行索引标签,则删除时会报错,这里可以看到输出结果正是删除了行索引为1和3的两行数据。这里值得注意的是:在执行删除操作后我们再次打印了原 data 数据集,通过输出可以看到,data 的数据并没有被影响到,还是完整的数据集。这里如果我们的 inplace 参数设置了 True,则对应的删除操作后,原数据就会被修改,通过下面的代码可以看到操作效果:# 删除指定行 等价于drop(labels=[0,1],axis=0)data_res=data.drop(labels=[1,3],axis=0,inplace=True )print(data_res)print(data)# --- 输出结果 ---None 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling2 C 1972年 33.9 Dennis MacAlistair Ritchie4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup输出解析:这里可以看到 data_res 的输出结果为 None ,而 data 原数据集则被删除了1和3的索引行。这是因为当我们设置了 inplace=True 时,drop() 操作后就不会返回一个新的数据集,而是在原数据集的基础上进行了操作,在实际应用中,如果不是特别的需要,建议不要指定该参数为 True,不然会改变原有数据对其他的分析产生一定的影响。

2.2 read_csv()函数

read_csv() 函数为 Pandas 读取 txt、csv 数据文件提供了强力的支持,该函数含有四五十个参数,默认是 从文件、URL、文件新对象中加载带有分隔符的数据,默认分隔符是逗号。下面我们列举出它最常用的几个参数。参数名称描述filepath_or_buffer可以是url,类型包括(http, ftp, s3和文件),比如上面我们 pandasDataDemo.txt 文件的位置为:C:\Users\13965\Documents\myFuture\IMOOC\pandasCourse-progress\data_source\pandasDataDemo.txt ,如果不指定类型,默认是 file 类型sep指定数据的分隔符,默认是 “,”header指定数据的从第几行解析,默认是文件数据的第1行,header=0,如果不用文件中的某行作为列名,要写上 header=Nonenames指定列名,如 names=[‘A’,‘B’,‘C’,‘D’,‘E’]nrows指定数据文件中读取多少行的数据,从数据第一行开始skiprows指定忽略的行数,从数据文件头开始skipfooter指定忽略的行数,从文件的尾部开始(c引擎不支持)encoding指定数据解析时,字符的集类型,通常指定为 “utf-8”engine指定数据分析的引擎,默认是 c,c 引擎虽然快但是 Python 引擎的功能更多。na_filter是否检查缺失值(空字符串或者是空值),当数据文件较大时,并且很少有缺失值,设置 na_filter=False能有效的提升读取的速度

3. 通道结合 select 流程控制

在 Go 语言中为了更方便的利用通道的功能,提供了一个仅用于通道的流程控制语句:select...case。使用这个语句可以同时监听数个通道,非常适合用于并发时的进程调度,或者模块之间的解耦合。这些在后续的文章中会有详细介绍,下面通过一个简单的例子来了解一下 select...case 语句。代码示例:package mainimport "fmt"func main() { c := make(chan int, 1) for a := 0; a < 2; a++ { select { case i := <-c: fmt.Println("从通道中取出", i) case c <- 10: fmt.Println("将 10 塞入通道中") } }}第 8 行:写一个两次的循环,若是在多线程中,一般写成死循环;第 9 行:select 关键字做为 select 语句的起始;第 10 行:若 c 通道中存在数据,则取出,并执行后续语句;第 12 行:若通道未满,将 10 塞入通道中。Tips:select 语句和 switch 语句一样,case 都只会执行一个,然后立刻跳出语句执行结果:

3. 不同类型的 nil 的长度不同

不同类型的变量的内存分配都是不同的,即使是 nil ,分配的内存也是不同的。代码示例:package mainimport ( "fmt" "unsafe")func main() { var m map[int]string var p *int var c chan int var s []int var f func() var i interface{} fmt.Println("map:", unsafe.Sizeof( m )) fmt.Println("指针:", unsafe.Sizeof(p)) fmt.Println("通道:", unsafe.Sizeof(c)) fmt.Println("切片:", unsafe.Sizeof(s)) fmt.Println("函数:", unsafe.Sizeof(f)) fmt.Println("接口:", unsafe.Sizeof(i))}执行结果:

4. 为什么要学习 NumPy ?

Numpy 是基于 C 语言开发,因此继承了 C 语言运算速度快、消耗资源少等优点,并且 Numpy 被广泛应用于数据分析、机器学习和深度学习等领域,因此掌握 Numpy 对能力提升和职场晋升的重要性不言而喻。

2.3 输出日志文件

控制台日志保存的内容十分有限,大多数情况下我们需要将日志写入文件,便于追溯。可以通过配置文件指定日志文件,如下配置会将日志打印到 C:\\logs\\spring-boot-log.log 文件中。实例:# 设置日志文件logging.file=C:\\logs\\spring-boot-log.log也可以指定日志文件输出的目录, Spring Boot 项目会在指定输出目录下新建 spring.log 文件,并在文件中写入日志。实例:# 设置日志目录logging.path=C:\\logsTips:如果同时配置了 logging.file 和 ogging.path ,则只有 logging.file 生效。

3. 使用场景及应用实例

时序图作为展示对象交互顺序的工具,可以更直观的描述顺序及并发过程。实例 9:学生使用教务系统时序图展示。sequenceDiagram participant a as 学生 participant b as 教务系统 participant c as 课程 participant d as 成绩 opt 认证 a->>b: 用户名/密码 end a->>+b: 请求课程列表 b->>+c: 获取课程列表 c-->>-b: 返回课程列表 b->>+d: 获取成绩信息 d-->>-b: 返回成绩信息 b-->>-a: 显示成绩其渲染效果如下:

1. 声明 <code>enum</code>

声明一个枚举类型,可以采用关键字 enum 加上一个自定义的名称,再加上一系列的枚举值。enum Score{ A = 5, B = 4, C = 3, D = 2, E = 1, F = 0};当让你也可以采用其默认值,默认情况下,枚举的数值是整数 0 开始的,然后递加 1 。enum Score{F, E, D, C, B, A};这个定义的枚举和之前介绍的那个效果是一致的。同时你还可以采用默认值与自定义值混合的方式来定义一个枚举。enum Score{ E = 1, F, D = 5, C, B = 0, A};在上面的定义中, E 的值为 1 , F 的值为 2 , D 的值为 5 , C 的值为 6 , B 的值为 0 , A 的值为 1 。

4.2 read_excel() 函数

Pandas 提供了 read_excel() 函数用于 Excel 数据文件的读取,并为其提供了很多的参数用于解析 Excel 数据的设置,接下来我们列举一些该函数中常用的几个参数设置:参数名称描述io传入 execl 文件的对象,字符串可能是一个 URL 包括的类型(http,ftp,s3和文件)sheet_name指定读取第几个 sheet 表,默认是第一个,sheet_name=None 可以读取所有的 sheetheader指定哪一行作为列名,如果不需要里面的行作为列名,要写上 header = Nonenames指定列名,如 names=[‘A’,‘B’,‘C’,‘D’,‘E’]1. 首先,我们通过 read_excel() 的 io 将 “execl数据demo.xlsx ”中的数据解析出来:# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/execl数据demo.xlsx"data = pd.read_excel(data_path)print(data)# --- 输出结果 --- 编程语言 推出时间 主要创始人0 java 1995年 James Gosling1 python 1991年 Guido van Rossum2 C 1972年 Dennis MacAlistair Ritchie3 js 1995年 Brendan Eich4 php 2012年 Rasmus Lerdorf5 C++ 1983年 Bjarne Stroustrup输出解析:这里是将 Excel 中的第一个工作表的数据解析出来 Excel 中行和列分别解析为行数据和列数据,默认第一行作为列名称。2. 参数 sheet_name该参数用于设置读取 Excel 数据中的哪个工作表,值为工作表名称,首先我们在 “execl数据demo.xlsx” 文件中新增一个工作表 Sheet2 ,数据的内容直接从工作表1 中复制,并为每一项数据添加 “_2” 作为区分:首先我们通过设置 sheet_name=‘Sheet2’ 来读取 Sheet2 中的数据:# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/execl数据demo.xlsx"# 这里我们传入参数 sheet_namedata = pd.read_excel(data_path,sheet_name='Sheet2')print(data)# --- 输出结果 ---编程语言_2 推出时间_2 主要创始人_20 java_2 1995年_2 James Gosling_21 python_2 1991年_2 Guido van Rossum_22 C_2 1972年_2 Dennis MacAlistair Ritchie_23 js_2 1995年_2 Brendan Eich_24 php_2 1996年_2 Rasmus Lerdorf_25 C++_2 1997年_2 Bjarne Stroustrup_2输出解析:这里可以看到解析的数据为 Sheet2 中的数据内容。接下来我们设置 sheet_name=None ,来解析所有工作表的数据:# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/execl数据demo.xlsx"# 这里我们传入参数 sheet_namedata = pd.read_excel(data_path,sheet_name=None)print(data)# --- 输出结果 ---{'Sheet1': 编程语言 推出时间 主要创始人0 java 1995年 James Gosling1 python 1991年 Guido van Rossum2 C 1972年 Dennis MacAlistair Ritchie3 js 1995年 Brendan Eich4 php 2012年 Rasmus Lerdorf5 C++ 1983年 Bjarne Stroustrup, 'Sheet2': 编程语言_2 推出时间_2 主要创始人_20 java_2 1995年_2 James Gosling_21 python_2 1991年_2 Guido van Rossum_22 C_2 1972年_2 Dennis MacAlistair Ritchie_23 js_2 1995年_2 Brendan Eich_24 php_2 1996年_2 Rasmus Lerdorf_25 C++_2 1997年_2 Bjarne Stroustrup_2}输出解析:可以看到输出结果是将 Sheet1 和 Sheet2 的数据都进行了解析,格式是字典形式,工作表名为 key,值是解析的工作表的数据值。3. 参数 headerheader 参数用于指定哪一行作为列名:# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/execl数据demo.xlsx"# 这里我们传入参数 header data = pd.read_excel(data_path,header =2)print(data)# ---输出结果--- python 1991年 Guido van Rossum0 C 1972年 Dennis MacAlistair Ritchie1 js 1995年 Brendan Eich2 php 2012年 Rasmus Lerdorf3 C++ 1983年 Bjarne Stroustrup输出解析:这里可以看到将第二行的数据解析为列名,并从改行详细继续解析数据。4. 参数 namesnames 用于手动传入列名的值:# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/execl数据demo.xlsx"# 这里我们传入参数 header data = pd.read_excel(data_path,names =["a1","a2","a3"])print(data)# ---输出结果--- a1 a2 a30 java 1995年 James Gosling1 python 1991年 Guido van Rossum2 C 1972年 Dennis MacAlistair Ritchie3 js 1995年 Brendan Eich4 php 2012年 Rasmus Lerdorf5 C++ 1983年 Bjarne Stroustrup输出解析:这里手动传入了列的名称为 a1 , a2 , a3。

2.2 匹配指定几个字符或范围字符

我们使用[],来匹配几个指定字符或者范围的字符。匹配所有带a、b、c的字符串。实例:def contains_abc(str) str =~ /[abc]/endcontains_abc('test')contains_abc('bell')contains_abc('apple')# ---- 输出结果 ----nil00匹配a~c的所有字符(abc)。实例:def contains_abc(str) str =~ /[a-c]/endcontains_abc('test')contains_abc('bell')contains_abc('apple')# ---- 输出结果 ----nil00解释:上述的例子表示,[a-c]和[abc]代表一样的内容。Tips:同样的[1-5]也代表[12345]。另外我们还有一个取反的操作。使用^。实例:def contains_abc(str) str =~ /[^a-c]/endcontains_abc('test')contains_abc('bell')contains_abc('apple')# ---- 输出结果 ----011解释:test第一个字符是t,符合不是a、b、c的正则所以返回索引0,bell的第一个字符b不匹配正则,而e匹配,所以返回索引1,apple的第一个字符a不匹配正则,p匹配,所以返回1。这些是常用匹配范围字符的正则:方法时机简介(调用的时机)\w同:[0-9a-zA-Z_]\d同:[0-9]\s同:匹配空格、制表符、换行符。\W同:[^0-9a-zA-Z_]\D同:[^0-9]\S同:不是空格、制表符、换行符。.可以匹配任意字符。.可以匹配任意字符,\.仅可以匹配.字符。实例:p "6b6" =~ /\d.\d/p "6b6" =~ /\d\.\d/p "6.6" =~ /\d\.\d/# ---- 输出结果 ----0nil0

2.2 基本使用

var obj = {a: 1, b: 2, c: 3};Object.values(obj) // [1, 2, 3]

3.2 键排序问题

上一节 我们学习 Object.keys() 会对属性是数值的键进行排序,在这个过程中属性对应的值也会跟着改变位置,所有使用 Object.values() 返回的数组是按 Object.keys() 顺序后的结果展示的,所以得到的值要和排序后的属性一一对应。var obj = {10: 'a', 1: 'b', 7: 'c'};Object.values(obj) // ['b', 'c', 'a']

3.6 pip3 show package-name

命令 pip3 show package-name 显示名称为 package-name 的第三方模块的信息,示例如下:C:\> pip3 show requestsName: requestsVersion: 2.23.0Summary: Python HTTP for Humans.Home-page: https://requests.readthedocs.ioAuthor: Kenneth ReitzAuthor-email: me@kennethreitz.orgLicense: Apache 2.0Location: c:\python3\lib\site-packagesRequires: chardet, idna, certifi, urllib3在以上信息中,requires 列出 requests 模块的依赖的模块:chardet、idna、certifi、urllib3,当安装 requests 模块时,会自动安装这 4 个模块。

4.RIGHT JOIN 右连接

同样以表 course 和 teacher 右连接为例:SELECT c.id AS course_id,c.*,t.* FROM course c RIGHT JOIN teacher t ON c.teacher_id=t.id;执行结果如下图:Tips:RIGHT JOIN 为右连接,是以右边的表为’基准’,若左表没有对应的值,用 NULL 来填补。

3.2 修改某类数据值

有时候我们需要对数据集中的一类数据进行修改,比如我们要将所有的“1995年”换成字符串“2000年”,这时我们就需要用到函数 replace(to_replace=None,value=None……),该函数的两个核心参数 to_replace 表示要被替换的数据,value 是替换后的数据,该函数修改后,会返回新的数据集,不会影响到原数据。# 导入pandas包import pandas as pd# 指定导入的文件地址data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第7,8,9,10小节/execl数据demo.xlsx"# 解析数据data = pd.read_excel(data_path)print(data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# 这里我们对 将所有的“1995年”数据修改为“2000年”new_data=data.replace("1995年","2000年")print(new_data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 2000年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 2000年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup输出解析:这里可以看到原数据中所有的“1995年”都被改成了“2000年”。这里我们要被修改的值也可以传入列表的形式,指定多个被修改的数据值,如下面代码所示:# 这里我们传入list数据集,对这几个数据进行修改为“2000年”new_data=data.replace(["1995年","2012年","1983年"],"2000年")print(new_data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 2000年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 2000年 59.5 Brendan Eich4 php 2000年 69.9 Rasmus Lerdorf5 C++ 2000年 75.0 Bjarne Stroustrup输出解析:通过输出结果可以看到,原数据集中的1995年,2012年,1983年都被修改为了“2000年”。

1. 概述

我们可以向 Android 项目添加 C 和 C++ 代码,只需将相应的代码添加到项目模块的 cpp 目录中即可。在我们构建项目时,这些代码会编译到一个可由 Gradle 与我们的 APK 打包在一起的原生库中。然后,Java 代码即可通过 Java 原生接口 (JNI) 调用原生库中的函数。Android Studio 支持适用于跨平台项目的 CMake,以及速度比 CMake 更快但仅支持 Android 的 ndk-build。目前不支持在同一模块中同时使用 CMake 和 ndk-build。要为我们的应用编译和调试原生代码,我们需要以下组件:Android 原生开发套件 (NDK):一个工具集,让我们能够在 Android 项目中使用 C 和 C++ 代码;它提供了各种平台库,让我们能够管理原生 Activity 并访问物理设备组件,例如传感器和轻触输入。CMake:一款外部编译工具,可与 Gradle 搭配使用来编译原生库。如果我们只计划使用 ndk-build,则不需要此组件。LLDB:Android Studio 用于调试原生代码的调试程序。默认情况下,LLDB 将与 Android Studio 一起安装。

3.2 CSV 数据文件的读取

Pandas 读取 CSV 文件用的也是 read_csv()函数,解析数据是默认的使用 “,” 进行划分列,当然对应的参数也是适用的,这里我们就不一一赘述,我们演示一下读取 csv 文件数据。# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/CSV数据Demo.csv"# 这里我们指定解析引擎为 pythondata = pd.read_csv(data_path, engine='python')print(data)# ---输出结果--- 编程语言 推出时间 主要创始人0 java 1995年 James Gosling1 python 1991年 Guido van Rossum2 C 1972年 Dennis MacAlistair Ritchie3 js 1995年 Brendan Eich4 php 2012年 Rasmus Lerdorf5 C++ 1983年 Bjarne Stroustrup

4.2 os.path.isfile(path)

操作系统中,常见的文件类型有两种:普通文件文本文件或者二进制数据文件被称为普通文件目录文件os.path.isfile(path) 判断文件是否为普通文件,该函数的使用示例:>>> import os>>> os.path.isfile('C:\\Windows\\notepad.exe')True>>> os.path.isfile('C:\\Windows')False

2.5 迭代 Set 和 Map

在 Set 和 Map 章节中我们就说到了,Set 和 Map 可以使用 for...of 来进行循环,主要因为 Set 和 Map 具有可迭代属性。let setArr = new Set([1, 1, 2, 2, 3, 3]);for (let value of setArr) { console.log(value);}// 1// 2// 3上面的代码需要注意的是,迭代的是 new Set() 后的结果,new Set() 会对数组进行去重操作,所以得到以上结果。let map = new Map([["a", 1], ["b", 2], ["c", 3]]);for (let value of map) { console.log(value);}// ["a", 1]// ["b", 2]// ["c", 3]上面的代码中使用 new Map() 传入一个二维数组,这里需要注意的是,迭代的结果是一个带有 key 和 value 的数组,所以也可以用数组解构的方式 把 key 和 value 的值取出来,直接使用:for (let [key, value] of map) { console.log(key, value);}// a 1// b 2// c 3

1.2 numpy.savez 函数

numpy.savez 函数可以将多个数组保存到以 npz 为扩展名的文件中。函数原型如下是:numpy.savez(file, *args, **kwds)参数说明如下:参数说明file要保存的文件,扩展名为 .npy,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上args要保存的数组kwds要保存的数组使用关键字名称案例定义数组:b = np.array([11, 22, 33, 44, 55, 66]) c = np.array([10, 20, 30, 40, 50, 60]) 将数组 a、b、c 保存到 outfile_abc.npz 文件上:np.savez('outfile_abc.npz', a, b, arr_1d = c)

2. 小结

对于 C 语言的注释,这里有两种方式:多行注释(经典式注释)单行注释(C++ 式注释)经典式可以注释多行,使用 /* */ 来进行注释,而 C++ 式的注释提供了更为便捷的注释方式,只能注释单行,使用 // 进行注释。大家可以根据实际需要选择。但是要切记,作为一个程序员良好的素养就是做好注释。没有注释的程序是不完整的程序,因为程序阅读的对象是人。

2. 镜像构建过程

我们执行 docker build --network=host -t ubuntu-nginx:v1 . 命令,看看在构建过程中做了哪些操作:[user@centos8 nginx]$ docker build --network=host -t ubuntu-nginx:v1 .# 将上下文求发送给Docker引擎Sending build context to Docker daemon 2.56kB# 下载依赖的镜像Step 1/7 : FROM ubuntulatest: Pulling from library/ubuntud51af753c3d3: Pull completefc878cd0a91c: Pull complete6154df8ff988: Pull completefee5db0ff82f: Pull completeDigest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7Status: Downloaded newer image for ubuntu:latest# 生成镜像 1d622ef86b13 ---> 1d622ef86b13Step 2/7 : MAINTAINER my_name myemail@domain.com# 运行容器 4eec6e3094f0,在容器内运行上面的这个命令,标记维护者信息 ---> Running in 4eec6e3094f0# 移除临时容器 4eec6e3094f0Removing intermediate container 4eec6e3094f0# 生成镜像 6679d1c204e3 ---> 6679d1c204e3Step 3/7 : RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list# 运行容器84d38c20d8c4,在容器内运行上面的这个命令,更换软件源记录 ---> Running in 84d38c20d8c4# 移除临时容器 84d38c20d8c4Removing intermediate container 84d38c20d8c4# 生成镜像 83f29f7b055a ---> 83f29f7b055aStep 4/7 : RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list# 运行容器 763e4493d93f, 在容器内运行上面的这个命令,更换软件源记录 ---> Running in 763e4493d93f# 移除临时容器 763e4493d93fRemoving intermediate container 763e4493d93f# 生成镜像 6297f20605d9 ---> 6297f20605d9Step 5/7 : RUN apt update >/dev/null 2>&1# 运行容器 2665a7e5a2e9,在容器内运行上面的这个命令, 更新软件源缓存 ---> Running in 2665a7e5a2e9# 移除临时容器 2665a7e5a2e9Removing intermediate container 2665a7e5a2e9# 生成镜像 fdfed940ca4d ---> fdfed940ca4dStep 6/7 : RUN apt install nginx -y >/dev/null 2>&1# 运行 容器 722a9a544643,在容器内运行上面的这个命令, 安装nginx ---> Running in 722a9a544643# 移除临时容器 722a9a544643Removing intermediate container 722a9a544643# 生成镜像 6ee76f7df9e5 ---> 6ee76f7df9e5Step 7/7 : EXPOSE 80# 运行容器 a12ed3216ee0,在容器内运行上面的这个命令, 暴露80端口 ---> Running in a12ed3216ee0# 移除临时容器 a12ed3216ee0Removing intermediate container a12ed3216ee0# 生成最终的镜像 7cf64279ba98 ---> 7cf64279ba98Successfully built 7cf64279ba98# 将这个镜像标记命名 ubuntu-nginx 版本号v1Successfully tagged ubuntu-nginx:v1结合之前讲到的 docker commit 命令,不难理解 Dockerfile 就是将我们在文件中书写的构建指令,一层一层从 FROM 指定的基础镜像使用临时容器过渡,逐层叠加起来最终生成目标镜像。使用 docker history ubuntu-nginx:v1 命令可以验证我们的想法:[user@centos8 nginx]$ docker history ubuntu-nginx:v1IMAGE CREATED CREATED BY SIZE COMMENT7cf64279ba98 21 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B6ee76f7df9e5 21 minutes ago /bin/sh -c apt install nginx -y >/dev/null 2… 59.2MBfdfed940ca4d 21 minutes ago /bin/sh -c apt update >/dev/null 2>&1 21.4MB6297f20605d9 21 minutes ago /bin/sh -c sed -i 's/security.ubuntu.com/mir… 2.76kB83f29f7b055a 21 minutes ago /bin/sh -c sed -i 's/archive.ubuntu.com/mirr… 2.76kB6679d1c204e3 21 minutes ago /bin/sh -c #(nop) MAINTAINER my_name myemai… 0B1d622ef86b13 2 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B<missing> 2 weeks ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B<missing> 2 weeks ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 811B<missing> 2 weeks ago /bin/sh -c [ -z "$(apt-get indextargets)" ] 1.01MB<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:a58c8b447951f9e30… 72.8MB

4. 示例

#include <stdio.h>int main(){ short a[2][2] = {{}, {3, 4}}; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { printf("a[%d][%d] = %d\n", i, j, a[i][j]); } } int b[][2] = {{1, 2}, {3, 4}}; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { printf("b[%d][%d] = %d\n", i, j, b[i][j]); } } int c[3][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}, {{9, 10}, {11, 12}}}; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { printf("c[%d][%d][%d] = %d\n", i, j, k, c[i][j][k]); } } } return 0;}运行结果:a[0][0] = 0a[0][1] = 0a[1][0] = 3a[1][1] = 4b[0][0] = 1b[0][1] = 2b[1][0] = 3b[1][1] = 4c[0][0][0] = 1c[0][0][1] = 2c[0][1][0] = 3c[0][1][1] = 4c[1][0][0] = 5c[1][0][1] = 6c[1][1][0] = 7c[1][1][1] = 8c[2][0][0] = 9c[2][0][1] = 10c[2][1][0] = 11c[2][1][1] = 12示例程序里面通过 3 种不同的方式初始化了 a、b、c 三个多维数组,其中 a 与 b 数组是 2 维数数组,c 是 3 维数组。这里在初始化数组的时候,我们采用通常建议的多层大括号的组织方式,这种方式虽然使用了更多的括号,但是可读性会更强,更有条理性。在多维数组的使用中,会采用多层的嵌套循环来进行内部全部变量的赋值或者取值操作,如果只是想对于数组中的某一个位置上的数值进行修改,只要直接使用其索引位置就可以了,如 a[0][1] = 100 等。

4.2 上线推送

private void login(LoginReqBean bean, Channel channel){ Channel c=map.get(bean.getUserid()); LoginResBean res=new LoginResBean(); if(c==null){ //1.添加到map map.put(bean.getUserid(),channel); //2.给通道赋值 channel.attr(AttributeKey.valueOf("userid")).set(bean.getUserid()); //3.登录响应 res.setStatus(0); res.setMsg("登录成功"); res.setUserid(bean.getUserid()); channel.writeAndFlush(res); //4.根据user查找是否有尚未推送消息 //思路:根据userid去lists查找....... }else{ res.setStatus(1); res.setMsg("该账户目前在线"); channel.writeAndFlush(res); }}

3.1 例1 笛卡尔积

请书写 SQL 语句得到imooc_class和imooc_user两表的笛卡尔积。分析:使用 Select 搭配 Cross Join 得到两表的笛卡尔积即可。语句:SELECT * FROM imooc_class CROSS JOIN imooc_user;+----+---------------+----+----------+----------+| id | class_name | id | username | class_id |+----+---------------+----+----------+----------+| 1 | SQL必知必会 | 1 | pedro | 1 || 2 | C语言入门 | 1 | pedro | 1 || 3 | JAVA高效编程 | 1 | pedro | 1 || 4 | JVM花落知多少 | 1 | pedro | 1 || 1 | SQL必知必会 | 2 | peter | 1 || 2 | C语言入门 | 2 | peter | 1 || 3 | JAVA高效编程 | 2 | peter | 1 || 4 | JVM花落知多少 | 2 | peter | 1 || 1 | SQL必知必会 | 3 | faker | 2 || 2 | C语言入门 | 3 | faker | 2 || 3 | JAVA高效编程 | 3 | faker | 2 || 4 | JVM花落知多少 | 3 | faker | 2 || 1 | SQL必知必会 | 4 | lucy | 4 || 2 | C语言入门 | 4 | lucy | 4 || 3 | JAVA高效编程 | 4 | lucy | 4 || 4 | JVM花落知多少 | 4 | lucy | 4 || 1 | SQL必知必会 | 5 | jery | <null> || 2 | C语言入门 | 5 | jery | <null> || 3 | JAVA高效编程 | 5 | jery | <null> || 4 | JVM花落知多少 | 5 | jery | <null> |+----+---------------+----+----------+----------+从结果中可以看出,交叉连接就是将一张表的每一条记录与另一张表的每一条记录进行连接成为一条新记录,排列组合完毕后得到两张表的笛卡尔积。交叉连接还可以通过隐式的连接方式来实现:SELECT * FROM imooc_class,imooc_user;

4.3 判断对象是文件还是目录

我们可以通过如下两个方法判断 File 对象是文件还是目录:boolean isFile():测试此抽象路径名表示的文件是否为普通文件;boolean isDirectory():测试此抽象路径名表示的文件是否为目录。实例如下:import java.io.File;public class FileDemo3 { public static void printResult(File file) { // 调用isFile()方法并接收布尔类型结果 boolean isFile = file.isFile(); String result1 = isFile ? "是已存在文件" : "不是已存在文件"; // 掉用isDirectory()方法并接收布尔类型而己过 boolean directory = file.isDirectory(); String result2 = directory ? "是已存在目录" : "不是已存在目录"; // 打印该file对象是否是已存在文件/目录的字符串结果 System.out.print(file); System.out.print('\t' + result1 + '\t'); System.out.println(result2); } public static void main(String[] args) { // 传入目录绝对路径 File dir = new File("C:\\Users\\Colorful\\Desktop\\imooc\\images"); // 传入文件绝对路径 File file = new File("C:\\Users\\Colorful\\Desktop\\imooc\\test.java"); FileDemo3.printResult(dir); FileDemo3.printResult(file); }}运行结果:C:\Users\Colorful\Desktop\imooc\images 不是已存在文件 是已存在目录C:\Users\Colorful\Desktop\imooc\test.java 不是已存在文件 不是已存在目录代码中我们封装了一个静态方法printResult(),此方法打印 File 对象是否是文件/目录。值得注意的是,我们的磁盘中不存在C:\Users\Colorful\Desktop\imooc\test.java,因此无论调用isFile()方法还是isDirectory()方法,其返回结果都为false。

3. 查询方法操作

这里我们通过解析 Excel 数据文件,获得了数据,具体数据解析内容如下:# 导入pandas包import pandas as pd# 指定导入的文件地址 默认是file,这里的路径中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第7,8,9,10小节/execl数据demo.xlsx"data = pd.read_excel(data_path)print(data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup输出解析:可以看到解析后的数据结构是 DataFrame 的二维数据表,有行索引和列索引,接下来我们将通过多种查询方式,对该二维数据进行查询。

直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号