为了账号安全,请及时绑定邮箱和手机立即绑定
2. 描述性统计函数

下面我们列举了几个常用的重要函数,上一节已经讲述了 count () , sum () , mean () 函数,这里我们将不再讲述:函数名说明 min 计算最小值 max 计算最大值 cumsum 计算累计总和 describe 计算汇总统计下面我们通过具体的代码数据实例看一下各个函数的应用。1. min() 和 max() 函数这两个函数分别用于计算指定数据集中的最小值和最大值,默认的 axis=0 ,按列进行计算。# 导入pandas包import pandas as pd# 初始化数据df1=pd.DataFrame([[96,92],[85,None],[69,90]], index=[['语文','数学','英语']], columns=[['期中考试','期末考试']])print(df1)# --- 输出结果 --- 期中考试 期末考试语文 96 92数学 85 89英语 69 90# min 求数据集的最小值df1.min()# --- 输出结果 ---期中考试 69期末考试 89# max 求数据集的最大值df1.max()# --- 输出结果 ---期中考试 96期末考试 92# 结果解析:通过 min() 和 max() 函数的操作,我们可以看到求出数据集中的最大值和最小值,默认是按列计算,也可以通过参数 axis=1 设置按行计算;# max 求数据集的最大值 axis=1df1.max(axis=1)# --- 输出结果 ---语文 96数学 89英语 902. cumsum() 函数该函数用于计算累计数值总和,默认的 axis=0 ,按列进行计算,通过数据处理效果要区分和 sum () 函数的区别。# 导入pandas包import pandas as pd# 初始化数据df1=pd.DataFrame([[96,92,89,94],[85,89,91,90],[69,90,89,88]], index=[['语文','数学','英语']], columns=[['月考1','月考2','月考3','月考4']])print(df1)# --- 输出结果 --- 月考1 月考2 月考3 月考4语文 96 92 89 94数学 85 89 91 90英语 69 90 89 88# cumsum 计算累计总和,默认是按列计算df1.cumsum()# --- 输出结果 --- 月考1 月考2 月考3 月考4语文 96 92 89 94数学 181 181 180 184英语 250 271 269 272# sum 计算总和,默认是按列计算df1.sum()# --- 输出结果 ---月考1 250月考2 271月考3 269月考4 272# 结果解析:cumsum() 函数是累计求和,默认是在列上计算,可以看到各个月考的行数据“数学”是“语文”加“数学”成绩的和,“英语”则是“语文”加“数学”加“英语”的和。而 sum() 函数则是计算每列数据的总和,对各行数据没有影响。3. describe() 函数该函数用于计算一些统计数据,提供数据集的基本信息,包括范围、大小、波动趋势等待,用于进一步数据的分析,该函数用于计算列数据。该函数有三个核心参数:参数名说明 percentile 可选参数,要包含在输出中的百分位数,在 0-1 之间,默认 [.25, .5, .75]include 可选参数,包括的不同数据类型列表,默认只计算数值型,当为 all 时汇总的是所有列的数据;当为 object 时,汇总的是字符串列的数据;当为 number 时,汇总的是数字列的数据。exclude 可选参数,排除的数据类型列表下面我们通过代码操作数据集看一下详细的使用方法:# 导入pandas包import pandas as pd# 初始化数据df1=pd.DataFrame([[96,92,89,94,'A级'],[85,89,91,90,'C级'],[69,90,89,88,'B级']], index=[['语文','数学','英语']], columns=[['月考1','月考2','月考3','月考4','表现级别']])print(df1)# --- 输出结果 --- 月考1 月考2 月考3 月考4 表现级别语文 96 92 89 94 A级数学 85 89 91 90 C级英语 69 90 89 88 B级# describe 函数df1.describe()# --- 输出结果 --- 月考1 月考2 月考3 月考4count 3.000000 3.000000 2.000000 3.000000mean 83.333333 90.333333 90.000000 90.666667std 13.576941 1.527525 1.414214 3.055050min 69.000000 89.000000 89.000000 88.00000025% 77.000000 89.500000 89.500000 89.00000050% 85.000000 90.000000 90.000000 90.00000075% 90.500000 91.000000 90.500000 92.000000max 96.000000 92.000000 91.000000 94.000000# 结果解析:可以看到 describe() 函数统计分析后,默认的是只计算数值型,包含了多种分析信息,count:数据数量,mean:平均值,std:标准差,min:最小值,25%,50%,75%:对应的百分位上的分位数(计算方式为最大值减去最小值乘以对应的百分位,再加上最小值),max:最大值。这些统计项能清晰的让我们了解一组数据集的数据情况,进而选择合适的分析模型进行分析。# describe 设置include=‘all’df1.describe(include='all')# --- 输出结果 --- 月考1 月考2 月考3 月考4 表现级别count 3.000000 3.000000 3.000000 3.000000 3unique NaN NaN NaN NaN 3top NaN NaN NaN NaN C级freq NaN NaN NaN NaN 1mean 83.333333 90.333333 89.666667 90.666667 NaNstd 13.576941 1.527525 1.154701 3.055050 NaNmin 69.000000 89.000000 89.000000 88.000000 NaN25% 77.000000 89.500000 89.000000 89.000000 NaN50% 85.000000 90.000000 89.000000 90.000000 NaN75% 90.500000 91.000000 90.000000 92.000000 NaNmax 96.000000 92.000000 91.000000 94.000000 NaN# 结果解析:通过设置 include='all' describe() 函数计算所有列的数据,并且针对字符串型的数据会有 unique:不同的值有多少;top:出现频率最高的;freq:重复的次数。# describe 排除数值列 exclude=‘number’df1.describe(exclude='number')# --- 输出结果 --- 表现级别count 3unique 3top C级freq 1# 结果解析:通过设置 exclude 排除数值列,可以看到最后的描述性统计只有字符串列的数据。

Numpy 的统计函数

NumPy 提供了很多统计函数,例如对数组求和、用于从数组中查找最小元素,最大元素,百分位标准差和方差等。常用的统计函数如下:函数说明sum对数组中的全部或沿着轴向的元素求和。mean、median求数组的算术平均值、中位数std、var分别为标准差和方差min、max最小值和最大值argmin、argmax分别为最小和最大元素的索引cumsum所有元素的累计和cumprod所有元素的累计积percentile计算数组的百分比分位数

3.19 字符计数

您可以使用count方法计算某一个字符在字符串中出现的次数。实例:str = "aaab"str.count("a")# ---- 输出结果 ----3str.count("b")# ---- 输出结果 ----1

2.COUNT函数统计总条数

以 student 表为例,先查看所有 student 信息: SELECT * FROM student;查询结果如下图:可以使用 COUNT() 函数统计全部学生数量:SELECT COUNT(*) FROM student;执行结果如下图:也可以对某一列使用 COUNT() 函数:SELECT COUNT(id) FROM teacher;执行结果如下图:Tips:如上图所示,COUNT(*) 或者 COUNT(id) 表示统计全部结果集条数 10,注意 COUNT() 函数也会对 NULL 值的数据进行统计。

1. 字符串函数

字符串函数是专门用来进行字符串操作的。C 语言提供了一个标准的函数库 string.h 。在这个函数库中大致存在了 22 个字符串的函数。我们这里所介绍的字符串函数是来自于这个标准函数库中比较常用的的一部分函数。除了这个函数库,还会有第三方的函数库提供的字符串的一些函数。这些不在本教程的讨论范围内。常用的字符串函数包含一下几个:序号函数功能1strlen(str1)获取 str1 字符串的长度2strcpy(str1,str2)将 str2 中的内容复制到 str1 中3strcat(str1,str2)将 str2 连接到 str1 的后面4strcmp(str1,str2)比较两个字符串,如果两个字符串一致则返回 0;如果 str1 大于 str2 则返回正数;如果 str1 小于 str2 则返回负数5strchr(str1,shar1)在 str1 中查找字符 char1 第一次出现的位置,返回该位置的指针|6|strstr(str1.str2)|在 str1 中查找字符串 str2 第一次出现的位置,返回该位置的指针

5.1 字符串函数

字符串函数主要提供了字符串类型的相关操作,就像在 javascript 中一样,Sass 提供的字符串函数可以获取字符串的长度,字符串的下标以及字符串中的大小写字母转换等等。5.1.1 quote ($ string) 和 unquote($ string)这两个函数我们放在一起讲解,它们都接收 1 个参数,参数是字符串类型,quote($string) 函数的返回结果是 以带引号的形式返回你传入的字符串,反之 unquote($string) 函数的返回结果是以不带引号的形式返回你传入的字符串,我们举例看下:string.quote(aaa) //=> "aaa"unquote("bbb") //=> bbb5.1.2 str-index($string, $substring)str-index($string, $substring) 函数接收 2 个参数,返回 $substring 在 $string 中的第一次出现的索引,如果在 $string 中不包含 $substring 则返回 null ,我们举例看下:str-index("abcde", "a") //=> 1str-index("abcde", "c") //=> 35.1.3 str-insert($string, $insert, $index)看见 insert 这个词我们就能猜到,这个函数是用于字符串的插入,str-insert($string, $insert, $index) 函数接收 3 个参数,第 1 个参数是一个字符串,第 2 个参数是要插入的字符串,第 3 个参数是插入的位置,返回结果是插入后的字符串:str-insert("abcde", "j", 1) //=> "jabcde"str-insert("abcde", "j", 4) //=> "abcjde"str-insert("abcde", "j", 100) //=> "abcdej"str-insert("abcde", "j", -20) //=> "jabcde"从上面的例子我们可以看到,当第 3 个参数大于 $string 的长度,将会插入到,末尾;反之,如果小于 $string 长度的负值,则会插入到开始位置。5.1.4 str-length($string)这个函数用于获取传入的字符串的长度,只接收一个字符串参数,返回值是它的长度,返回值是 number 类型,我们举例看下:str-length("abcde") //=> 55.1.5 str-slice($string, $start-at, $end-at)这个函数用于字符串的截取,str-slice($string, $start-at, $end-at) 函数接收 3 个参数,第 1 个参数是一个字符串,第 2 个参数是要截取的开始位置,第 3 个参数是要截取的结束位置,返回结果是截取到的字符串;要记住 Sass 的字符串截取函数返回的字符串是包含截取的开始和结束位置字符的,我们举例看下:str-slice("abcde", 1, 2) //=> "ab"str-slice("abcde", 2, 4) //=> "bcd"5.1.6 to-upper-case($string) 和 to-lower-case($string)这两个函数我们放在一起来讲解,它们都接收 1 个字符串参数;to-upper-case($string) 函数 将传入的字符串转换为大写并返回,to-lower-case($string) 函数将传入的字符串转换为小写并返回:to-upper-case("abcde") //=> "ABCDE" 转为大写to-upper-case("Abc") //=> "ABC" 转为大写to-lower-case("ABC") //=> "abc" 转为小写to-lower-case("Abc") //=> "abc" 转为小写5.1.7 unique-id()unique-id() 函数会返回一个随机的字符串,并且这个字符串在 Sass 编译中是唯一的,这个我们用得不多,不过当你需要生成一个唯一的字符串标识的时候你可以使用它:unique-id() //=> urgdjis上面我们讲解了字符串函数,字符串函数可以让你方便地操作字符串,还为你提供了对字符串的增删改查功能,下面我们来讲解数字函数。

MySQL 的系统函数

MySQL 提供了很多的系统函数,这些系统函数可以对数据进行特殊的处理,下面表格列举了大部分的系统函数,本小节选择一些代表性的系统函数演示说明。函数名说明CONCAT(str0,str1)将两个字段的值拼接在一起CONCAT_WS(“拼接符”,str0,str1)将两个字段的值使用指定拼接符拼接在一起GROUP_CONCAT(expr)将指定分组的字段内容拼接在一起UPPER(str)将字符串包含的英文字符小写转化成大写lOWER(str)将字符串包含的英文字符大写转化成小写INITCAP(str)将字符串的首字母变成大写LENGTH(str)获取字符串的长度SUBSTR(str FROM pos FOR len)截取字符串,其中 pos 表示其实位置,len 表示结束位置TRIM(str)去除字符串两边空格INSTR(str,substr)查找指定字符在字符串的中的位置,其中 substr 表示需要查找的字符,例如 'Tom' 中 'T' 的位置为 1,'m' 的位置为 3LPAD(str,len,padstr)左填充,其中 len,表示字符串总长度,padstr 表示填充的字符RPAD(str,len,padstr)右填充,其中 len,表示字符串总长度,padstr 表示填充的字符LEFT(str,len)取一个字符串的前多少位RIGHT(str,len)取一个字串的后多少位CEIL(X)向上取整FLOOR(X)向下取整MOD(N,M)取余,例如 MOD(age,5),将字段 age 除以 5,除不尽的取余数POWER(X,Y)幂运算,例如 MOD(age,2),获取字段 age 值的 2 次方的值NOW()获取当前日期和时间CURDATE()获取当前日期,不包含时间CURTIME()获取当前时间,不包含日期YEAR(now())获取当前的年份HOUR(NOW())获取当前时间的小时数MINUTE(now())获取当前时间的分钟数SECOND(NOW())获取当前时间的秒数MONTHNAME(now())获取当前日期的英文月份MONTH(NOW())获取当前日期的数字月份DATE_ADD(date,INTERVAL expr unit)查询日期的变化,例如 DATE_ADD(‘2020-03-03’,INTERVAL 10 day) 表示 2020-03-03 十天之后的日期DATEDIFF(expr1,expr2)日期差,例如 DATEDIFF('2019-12-29','2019-12-01') 表示 2019-12-29 距离 2019-12-01 的天数DATE_FORMAT(date,format)将指定日期转化为自定义格式,例如 DATE_FORMAT('2019-12-29','%m/%d/%y') ,其中 %m 表示前面对应的月份,%d 表示前面对应的日期的天数,%y 表示前面对应的年份STR_TO_DATE(str,format)将指定日期转化为自定义格式,例如 DATE_FORMAT('12-29-2019','%m/%d/%y')DATE_FORMAT(date,format)将指定日期转化为自定义格式,例如 DATE_FORMAT('2019/12/29','%m/%d/%y')MD5(str)对字符串进行 MD5 转换UNIX_TIMESTAMP()将指定日期转化为时间戳COUNT()获取查询结果集条数AVG(expr)获取指定列平均值SUM(expr)获取指定字段值的总和MIN(expr)获取指定字段值的最小值MAX(expr)获取指定字段值的最大值

5.2 数字函数

Sass 提供了很多数字函数来提供计算和数值转换等功能,在 Sass 中我们也称之为 Math 函数,就像 javascript 中提供的 Math 函数一样,为我们提供了很多数学上的计算,首先我们先举例看一下简单的仅有数学计算意义的数字函数:math.$e //=> 2.7182818285 返回数学常数 e 的值math.$pi //=> 3.1415926536 返回数学常数 π 的值ceil(4.2) //=> 5 向上取整floor(4.8) //=> 4 向下取整round(4.3) //=> 4 四舍五入取近似值round(4.7) //=> 5 四舍五入取近似值abs(-10px) //=> 10px 取绝对值math.cos(100deg) //=> -0.1736481777 返回余弦值,单位必须与deg兼容或无单位math.sin(100deg) //=> 0.984807753 返回正弦值,单位必须与deg兼容或无单位math.tan(100deg) //=> -5.6712818196 返回正切值,单位必须与deg兼容或无单位math.acos(0.5) //=> 60deg 返回反余弦值,传入的参数不可带单位math.asin(0.5) //=> 30deg 返回反正弦值,传入的参数不可带单位math.atan(10) //=> 84.2894068625deg 返回反正切值,传入的参数不可带单位random() //=> 返回一个 0~1 之间的随机数percentage(0.2) //=> 20% 将无单位的小数转换为百分比数5.2.1 math.log($number, $base)这个函数用于计算对数,它会返回 $number 相对于 $base 的对数,这两个参数是不可以带有单位的。math.log(10) //=> 2.302585093math.log(10, 10) //=> 15.2.2 math.pow($base, $exponent)math.pow($base, $exponent) 函数用于计算 $base 的 $exponent 次幂,是用于幂运算的。math.pow(10, 2) //=> 1005.2.3 math.sqrt($number)math.sqrt($number) 函数返回传入参数的平方根。math.sqrt(100) //=> 105.2.4 comparable($number1, $number2)comparable($number1, $number2) 用来判断两个数值的单位是否兼容,它的返回结果是布尔值,这个在你需要对单位进行要求的时候很有用,我们举例看下:comparable(10px, 10) //=> truecomparable(10px, 10px) //=> truecomparable(10px, 10em) //=> false5.2.5 unitless($number)unitless($number) 用于判断传入的数值是否没有单位,返回结果是布尔值,如果没带单位返回 true,带单位则返回 false。unitless(100) //=> trueunitless(100px) //=> false5.2.6 unit($number)unit($number) 函数会返回传入数值的单位,并且是将单位以字符串的形式返回的,我们来看下:unit(8) //=> ""unit(8px) //=> "px"unit(8em) //=> "em"5.2.7 max(KaTeX parse error: Expected 'EOF', got '和' at position 12: number...) 和̲ min(number…)这两个函数分别接收以逗号分隔的数值,并且分别返回其中最大的值和最小的值。math.max(8, 4) //=> 8math.min(8, 4) //=> 4上面我们讲了 Sass 中数字函数,这些函数是辅助你来对数字类型的值进行一些操作,很像 javascript 中提供的 Math 函数,你不需要死记硬背,这些函数需要用到的时候再查也可以。

5.2 使用函数替换字符串

参数 replace 用于替换匹配的字符串,它可以是一个函数。下面的例子将匹配的数字乘以 2:import redef replace(matchedObject): text = matchedObject.group() number = int(text) return str(number * 2)line = 'number = 123'result = re.sub('\d+', replace, line)print(result)在第 8 行,定义了原始字符串 line在第 9 行,使用 re.sub 搜索符合模式 ‘\d+’ 的字符串,使用函数 replace 进行替换re.sub 找到符合模式 ‘\d+’ 的字符串时,将匹配结果传递给 replace函数 replace 根据匹配结果,返回一个字符串re.sub 将符合模式的字符串替换为函数 replace 的返回结果在第 3 行,定义了函数 replace在第 4 行,matchedObject.group() 返回匹配模式的字符串在第 5 行,将匹配的字符串转换为整数在第 6 行,将整数乘以 2 后转换为字符串,并返回程序输出结果如下:number = 246

2.2 不影响字符串长度或内容的函数

序号函数说明 1str.len() 计算字符串的长度 2str.contains() 查询字符串是否包含某个字符或子字符串 3str.find() 查询元素第一次在字符串中出现的位置 4str.count() 查询某个元素出现的次数 5str.startswith() 查询字符串是否以某个元素开头 6str.endswith() 查询字符串是否以某个元素结尾 7str.istitle() 查询字符串是否首字母大写其他都是小写下面我们将通过代码操作详细介绍这几个函数的使用方法:1. len() 函数该函数用于返回字符串的的长度,包括空格和回车符。# 导入pandas包import pandas as pddata_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第16小节/execl数据demo.xlsx"# 解析数据data = pd.read_excel(data_path)print(data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# len() 函数new_series=data["主要创始人"]slice_res= new_series.str.len() print(slice_res)# --- 输出结果 ---0 131 172 263 124 145 17Name: 主要创始人, dtype: int64结果解析:通过该函数可以输出字符串的长度,“主要创始人” 列的第二个字符加上空格和回车符工 17 个字符,如果字符前后存在空格,也是加入计算的。2. contains() 函数该函数用于检测字符串是否包含某个字符或者是子串,返回值为布尔型。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# contains() 函数new_series=data["编程语言"]slice_res= new_series.str.contains("com") print(slice_res)# --- 输出结果 ---0 False1 True2 False3 True4 False5 FalseName: 编程语言, dtype: bool结果解析:通过该函数检测 “编程语言” 列,字符串是否含有子串 com ,该列只有第 2 行和第 4 行含有 com 子串,所以这两行的检测结果为 True,其他行为 False。3. find() 函数该函数用于检测字符串中第一次出现某个子串或者字符的下标位置,如果不存在则返回为 -1。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# find() 函数new_series=data["编程语言"]slice_res= new_series.str.find("com") print(slice_res)# --- 输出结果 ---0 -11 112 -13 64 -15 -1Name: 编程语言, dtype: int64 结果解析:通过该函数进行检测,可以看到 “编程语言” 列中字符串出现 com 子串的位置下标,第 2 行为 11,第 4 行为 6,其他行因为不存在该子串,所以返回 - 1。4. count() 函数该函数用于统计字符串中出现某个子串或者字符的次数。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# count() 函数new_series=data["编程语言"]slice_res= new_series.str.count("o") print(slice_res)# --- 输出结果 ---0 01 22 03 14 05 0Name: 编程语言, dtype: int64 结果解析:通过该函数检测 “编程语言” 列,各个字符串中出现字符 ‘o’ 的次数,通过输出结果可以看到每一个子串中该字符出现的次数。5. startswith() 函数该函数用于检测字符串是否以某个字符或者子串开始,返回结果为布尔型。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# startswith() 函数new_series=data["编程语言"]slice_res= new_series.str.startswith("j") print(slice_res)# --- 输出结果 ---0 True1 False2 False3 True4 False5 FalseName: 编程语言, dtype: bool结果解析:通过该函数,检测 “编程语言” 列各个字符串是否以字符 ‘j’ 开始,可以看到输出结果只有第 1 行和第 4 行是的。6. endswith() 函数该函数用于检测字符串是否以某个字符或者子串结尾,返回结果为布尔型。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# endswith() 函数new_series=data["编程语言"]slice_res= new_series.str.endswith("p") print(slice_res)# --- 输出结果 ---0 False1 False2 False3 False4 True5 FalseName: 编程语言, dtype: bool# 结果解析:通过该函数对“编程语言”列的字符串进行检测,是否以字符 'p' 结尾,通过输出结果可以看到只有第5行的 "php" 是以该字符为结尾的,检测结果为 True 。 7. istitle() 函数该函数用于检测字符串中每个单词是否以大写字符开头,并且其他的字符均为小写的内容,这里要注意,检测的单位是字符串中的每个单词。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# istitle() 函数new_series=data["主要创始人"]slice_res= new_series.str.istitle() print(slice_res)# --- 输出结果 ---0 True1 False2 False3 True4 True5 TrueName: 主要创始人, dtype: bool结果解析:通过该函数检测 “主要创始人” 列中各个字符串的每个单词是否以大写字母开头,该单词的其他字符为小写,因为第 2 行字符串的 “van” 单词不是以大写字母开头,所有为 False,第 3 行字符串的 “MacAlistair” 虽然是以大写字符开头,但是该单词的其他字符不全是小写,因此也是返回 False 。

C 语言中的字符串函数

C 语言中的字符串虽然不是一种独立的数据类型,但是这并不影响其重要地位,所以在 C 语言中会有一些专门针对字符串的函数。

new 运算符与构造函数

当一个函数被 new 运算符调用的时候,这个函数就会被称为构造函数。任何函数都能被 new 运算符调用,但是一般会从设计上将一个函数考虑为构造函数,提供给 new 运算符调用。function Human(name, gender) { this.name = name; this.gender = gender;}var human = new Human();

2. 字段表计数器和字段表

上节课程抛出了问题,接口索引集合后边紧跟的结构是什么?这里我们来进行解答,后边紧跟的是字段表计数器,字段表计数器后边紧跟的是字段表。定义:字段表计数器(fields_count)与字段表不可分割,这里我们对两部分结构一起讲解。字段表计数器(fields_count):记录字段表中字段的数量,为无符号数类型。字段表(fields):字段表(fields)用于描述接口或者类中声明的变量。字段(field)包括类级变量(即静态变量)以及实例变量(即:非静态变量),但不包括在方法内部声明的局部变量。字段表为表类型结构。Tips:这里请学习者特别关注下字段表定义介绍中的最后两句话:“字段(field)包括类级变量(即静态变量)以及实例变量(即:非静态变量),但不包括在方法内部声明的局部变量。“ 简单的总结这句话的意思是字段表中存储的是全局标量,不存储局部变量。字段表计数器无符号数结构示意图:与其他计数器一样,字段表计数器(fields_count)是一个无符号数结构类型的数据,u2 大小。字段表-表结构类型示意图:字段表是一个表结构的类型数据,回忆下我们接触到的第一个 Class 文件的表结构类型数据为常量池。这里我们来看下字段表的表结构示意图。前文提到过,字段(field)包括类级变量(即静态变量)以及实例变量(即:非静态变量),上图所示的一个 field_info 就代表了一个变量。为了表示一个变量,需要知道这个变量的修饰符,如 public,还需要知道这个变量的变量名称,因此一个 field_info 中存储了很多特征值,所有的特征值综合起来就完整的描述了一个变量。

2.1 影响字符串长度或内容的函数

序号函数说明 1str.split() 拆分字符串 2str.slice() 按给定的位置截取字符串 3str.strip() 删除字符串中的空格或者换行符 4str.lower() 将字符串转换为小写 5str.upper() 将字符串转换为大写 6str.cat() 连接字符串列 7str.replace() 替换字符串中的元素 8str.swapcase() 字符串中的大小写互换下面我们将通过代码操作详细介绍这几个函数的使用方法:1. split() 函数该函数根据指定的元素分割字符串。# 导入pandas包import pandas as pddata_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第16小节/execl数据demo.xlsx"# 解析数据data = pd.read_excel(data_path)print(data)# --- 输出结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# split() 函数new_series=data["编程语言"]split_res= new_series.str.split("@")print(split_res)# --- 输出结果 ---0 [java]1 [python, 163.com]2 [C]3 [js, qq.com]4 [php]5 [C++ ]Name: 编程语言, dtype: object结果解析:首先我们获得 DataFrame 的 “编程语言” 列,返回的数据结构为 Series ,我们通过 str 属性的 split () 函数,传入分割依据的字符,通过结果可以看到,存在 @ 字符的字符串均被分割成了多个子元素,返回结果也是由列表构成的 Series 数据集。2. slice() 函数该函数根据给定开始和结束的下标位置,截取字符串,注意是左闭右开,不包含右边的下标位置,该函数有三参数:start :开始下标 stop :结束下标 step :步长# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustru# data 解析出来的数据# slice() 函数new_series=data["编程语言"]slice_res= new_series.str.slice(2,4)print(slice_res)# --- 输出结果 ---0 va1 th2 3 @q4 p5 + Name: 编程语言, dtype: object结果解析:这里我们指定 "编程语言" 列每个字符串从下标 2 截取到下标 4,因为下标是从 0 开始的,因此也就是截取每个字符串中第 3 和第 4 个字符,可以看到每个输出的结果。3. strip() 函数该函数会去掉字符串中头和尾的空格已经换行符。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustru# data 解析出来的数据# strip() 函数new_series=data["编程语言"]slice_res= new_series.str.strip()print(slice_res)# --- 输出结果 ---0 java1 python@163.com2 C3 js@qq.com4 php5 C++Name: 编程语言, dtype: object结果解析:通过输出结果可以看到,“C++” 中原数据后面有空格在,使用函数操作后,空格被删除。4. lower() 函数该函数用于将字符串中的所有大写字母转换为小写字母。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustru# data 解析出来的数据# lower() 函数new_series=data["编程语言"]slice_res= new_series.str.lower() print(slice_res)# --- 输出结果 ---0 java1 python@163.com2 c3 js@qq.com4 php5 c++ Name: 编程语言, dtype: object结果解析:通过输出结果可以看到,“编程语言” 列所有的大写字母都转换成了小写。5. upper() 函数该函数用于将字符串中的所有小写字母转换为大写字母。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustru# data 解析出来的数据# upper() 函数new_series=data["编程语言"]slice_res= new_series.str.upper() print(slice_res)# --- 输出结果 ---0 JAVA1 PYTHON@163.COM2 C3 JS@QQ.COM4 PHP5 C++ Name: 编程语言, dtype: object结果解析:通过输出结果可以看到,"编程语言" 这一列所有的小写字母均转换为了大写字母。6. cat() 函数该函数用于将两列合并成一列数据,前提是两列都是字符,如果是数值的话会报错。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# cat() 函数new_series=data["编程语言"]new_series_two=data["主要创始人"]slice_res= new_series.str.cat(new_series_two) print(slice_res)# --- 输出结果 ---0 javaJames Gosling1 python@163.comGuido van Rossum\n2 CDennis MacAlistair Ritchie3 js@qq.comBrendan Eich4 phpRasmus Lerdorf5 C++ Bjarne StroustrupName: 编程语言, dtype: object结果解析:通过 cat () 函数,将 “编程语言” 和 “主要创始人” 两列进行合并,可以看到输出结果中的合并结果。7. replace() 函数该函数可用于替换字符串的内容。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# replace() 函数new_series=data["编程语言"]slice_res= new_series.str.replace("com","cn") print(slice_res)# --- 输出结果 ---0 java1 python@163.cn2 C3 js@qq.cn4 php5 C++ Name: 编程语言, dtype: object 结果解析:这里我们将 “编程语言” 列字符串中的 com 替换为 cn,通过输出结果可以看到替换的效果。8. swapcase() 函数该函数用于将字符串中的大小写进行相互转换(大写转换为小写,小写转换为大写)。# --- 解析 data 数据结果 --- 编程语言 推出时间 价格 主要创始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出来的数据# swapcase() 函数new_series=data["主要创始人"]slice_res= new_series.str.swapcase() print(slice_res)# --- 输出结果 ---0 jAMES gOSLING1 gUIDO VAN rOSSUM\n2 dENNIS mACaLISTAIR rITCHIE3 bRENDAN eICH4 rASMUS lERDORF5 bJARNE sTROUSTRUPName: 主要创始人, dtype: object 结果解析:这里我们通过 swapcase 函数将 “主要创始人” 列中字符串的大小写进行了互换,通过输出结果可以看到互换的效果。

6.1 字符串的值

Kotlin 有两种类型的字符串字面值:转义字符串可以有转义字符, 以及原始字符串可以包含换行以及任意文本。以下是转义字符串的一个示例:val s = "Hello, world!\n"转义采用传统的反斜杠方式。字符串使用三个引号(""")分界符括起来,内部没有转义并且可以包含换行以及任何其他字符:val text = """ for (c in "foo") print(c)"""还可以通过 trimMargin() 函数去除前导空格:val text = """ |Tell me and I forget. |Teach me and I remember. |Involve me and I learn. |(Benjamin Franklin) """.trimMargin()

4.1 统计单词个数

本节基于前面已经实现的迭代器,完成统计单词个数的任务,代码如下:file = open('test.txt')count = 0for word in IterateWord(file): print(word) count = count + 1在第 1 行,打开文件 test.txt在第 2 行,变量 count 用于记录文件中单词的个数在第 4 行,遍历文件中的每一个单词在第 5 行,打印当前遍历的单词在第 6 行,统计单词个数程序运行输出结果如下:TheZenofPythonBeautifulisbetterthanuglySimpleisbetterthancomplexcount = 14

3.1 如何获取 Unicode 字符串的长度

我们可以使用 tf.strings.length 函数来获取 Unicode 字符串的长度,该函数含有两个重要的参数:str,要获取长度的字符串;unit,长度的单位,目前包含两个选项,一个是“BYTE”,另一个是“UTF8_CHAR”:BYTE,按照字节进行计数,从而获取字符串的长度;UTF8_CHAR,按照单个 Unicode 字符的单位进行计数,获取我们通常认知的长度。同时该 API 返回的是一个 Tensor ,我们可以通过 numpy() 函数来将其转化为我们可以直接使用的数字长度。比如以下代码:len_bytes = tf.strings.length(ch_string_utf_8, unit='BYTE')len_chars = tf.strings.length(ch_string_utf_8, unit='UTF8_CHAR')print(len_bytes, len_chars)print(len_bytes.numpy(), len_chars.numpy())我们可以得到如下输出:tf.Tensor(12, shape=(), dtype=int32) tf.Tensor(4, shape=(), dtype=int32)12 4可以看到,“你好呀!”字符串含有 12 个字节长度,而且正如我们看到的那样,包含 4 个汉字字符。

Python 内置函数

Python 解释器内置了很多函数,不用 import 即可使用这些内置函数。本小节讲解了 Python 中常见的内置函数,我们将这些函数分为 7 大类:类别功能系统帮助获取函数的使用帮助文件 IO读取标准输入、写标准输出、打开文件类型转换将整数转换为字符串、将字符串转换为整数数学运算常见的数学运算函数,例如:max 和 min复合数据类型列表、元组、字典等数据类型的构造对序列的操作对序列进行排序、筛选、映射面向对象相关判断类型之间的归属关系

1. 获取字符串长度

在往数据库中写入数据的时候,数据库字段通常都会有长度限制,所以在写入之前最好事先判断一下字符串的长度是否符合自己的设计。代码示例:package mainimport ( "fmt" "strings")func main() { str := "Hello Codey!" fmt.Println(len(str)) fmt.Println(strings.Count(str, "")-1)}执行结果:其实获取字符串长度常用的是用 len() 函数去获取,因为 sring 的本质是一个 rune 切片,所以 len() 对 string 也是可以直接使用的。如果想要通过 strings 包来获取长度,我们可以通过 strings.Count(str,s string)int 来迂回达到目的,寻找字符串中的空字符串的个数就相当于寻找字符之间的空隙(包括字符首尾),所以得到的数字就是长度+1,我们得到结果后再减去1,就可以得到字符串的长度了。

2. Pandas 字符串操作

Pandas 对字符串的操作是基于 Series 对象的 str 属性,该属性表示就是字符串对象,他下面封装了多种字符串操作函数,正是通过这些函数,我们可以方便的处理字符串,值得注意的是,Pandas 中的这些操作函数是单独封装的,实现上不同于 python 语言自带的字符串操作函数,使用起来更加的便捷,效率也更高。另外,Pandas 的 DataFrame 数据对象是不含该属性的,因此也不具有相应的字符串操作函数,但是我们在实际应用中,往往会根据需要获取 DataFrame 的数据子集返回 Series 数据对象,在通过 str 属性进行字符串的操作。Pandas 中提供了大量的字符串操作方法,我们这里依据是否影响字符串长度或内容,选取了 Pandas 库中常用的一些字符串操作函数进行详细讲解。**Tips:** 字符串中的操作函数,是区分大小写的,这点在使用时要注意。在讲解之前,我们还是先把 Excel 中的数据做一下处理,方便我们后面各个函数操作效果的呈现。解析后输出的数据结果:

2.3 将整数转换为字符串

Python 提供函数 str 用于将整数转换为字符串,例如:>> a = 1>> b = 1>> x = str(a)>> y = str(b)>> x + y'11'在第 3 行,将整数 a 转换为字符串 x 在第 4 行,将整数 b 转换为字符串 y 在第 5 行,将字符串 x 和字符串 y 相加,得到结果 ‘11’

3.2 将数值转换为字符串

>>> string = str(123)>>> string'123'>>> string = str(123.456)>>> string'123.456'函数 str(number) 将数值转换为字符串str(123) 将整数转换为字符串str(123.456) 将浮点数转换为字符串

2.2 将字符串转换为整数

Python 提供函数 int 用于将字符串转换为整数。使用 int 函数重写以上程序如下:>> a = input()'1'>> b = input()'1'>> x = int(a)>> y = int(b)>> x + y2在第 5 行,将字符串 a 转换为整数 x 在第 6 行,将字符串 b 转换为整数 y 在第 7 行,将整数 x 和整数 y 相加,得到结果 2将 input 返回的结果从将字符串转换为整数后,我们得到了预期的结果。

4. 函数重载

函数重载是指函数根据传入不同的参数,返回不同类型的数据。它的意义在于让你清晰的知道传入不同的参数得到不同的结果,如果传入的参数不同,但是得到相同类型的数据,那就不需要使用函数重载。比如面试中常考的字符反转问题,这里就不考虑负数情况了,只是为了演示函数重载:function reverse(target: string | number) { if (typeof target === 'string') { return target.split('').reverse().join('') } if (typeof target === 'number') { return +[...target.toString()].reverse().join('') }}console.log(reverse('imooc')) // coomiconsole.log(reverse(23874800)) // 847832编译器并不知道入参是什么类型的,返回值类型也不能确定。这时可以为同一个函数提供多个函数类型定义来进行函数重载。(通过 --downlevelIteration 编译选项增加对生成器和迭代器协议的支持)341代码解释:因为这个反转函数在传入字符串类型的时候返回字符串类型,传入数字类型的时候返回数字类型,所以在前两行进行了两次函数类型定义。在函数执行时,根据传入的参数类型不同,进行不同的计算。为了让编译器能够选择正确的检查类型,它会从重载列表的第一个开始匹配。因此,在定义重载时,一定要把最精确的定义放在最前面。

2.3 函数参数

上述我们了解了函数的定义,在其中无参函数调用即调用函数名即可,对于有参函数,需要传递一定的参数来执行对应的操作,函数的参数和脚本的参数类型及用法一致,在此我们简单回顾下,看参数在函数中都有哪些分类,及该如何使用。2.3.1 位置参数位置参数顾名思义,就是传递给函数参数的位置,例如给一个函数传递一个参数,我们可以在执行 Shell 脚本获取对应位置的参数,获取参数的格式为:$n。n 代表一个数字,在此需要注意与脚本传递参数不一样,$0 为依旧为脚本的名称,在函数参数传递中,例如传递给函数的第一个参数获取就为 $1,第 2 个参数就为 $2, 以此类推……,需要其 $0 为该函数的名称。例如:[root@master func]# cat f1.sh #!/bin/bashfunction f1() { echo "函数的第一个参数为: ${1}" echo "函数的第二个参数为: ${2}" echo "函数的第三个参数为: ${3}"}# 调用函数f1 shell linux python go[root@master func]# bash f1.sh 函数的第一个参数为: shell函数的第二个参数为: linux函数的第三个参数为: python我们可以看到传递给 f1 函数共 4 个位置参数,在结果输出中可以看到由于函数体内部只对三个参数进行了处理,后续的参数也就不再处理了。2.3.2 特殊参数在 Shell 中也存在特殊含义的参数如下表:变量含义$#传递给函数的参数个数总和$*传递给脚本或函数的所有参数,当被双引号 " " 包含时,所有的位置参数被看做一个字符串$@传递给脚本或函数的所有参数,当被双引号 " " 包含时,每个位置参数被看做独立的字符串$?$? 表示函数的退出状态,返回为 0 为执行成功,非 0 则为执行失败示例:[root@master func]# cat f1.sh #!/bin/bashfunction fsum() { echo "函数第一个参数为: ${1}" echo "函数第二个参数为: ${2}" echo "函数第三个参数为: ${3}" echo "函数的参数总数为: ${#}" echo "函数的参数总数为: ${@}" local sum=0 for num in ${@}; do let sum=${sum}+${num} done echo "计算的总和为: ${sum}" return 0}# 调用函数fsum 10 20 1 2echo $?[root@master func]# bash f1.sh 函数第一个参数为: 10函数第二个参数为: 20函数第三个参数为: 1函数的参数总数为: 4函数的参数总数为: 10 20 1 2计算的总和为: 330如上可以看到特殊参数与 Shell 脚本传递参数一样。Tips:局部变量需要特别声明在函数内部利用 local 关键字来声明。

5.1 替换字符串

函数 re.sub(pattern, replace, string, count=0, flags=0) 用于替换字符串:在字符串 string 中查找与模式 pattern 匹配的子串,将其替换为字符串 replace参数 replace,是被替换的字符串,也可为一个函数参数 count,模式匹配后替换的最大次数,默认 0 表示替换所有的匹配参数 flags,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等import reline = 'number = 123 # this is comment'result = re.sub('\d+', 'NUMBER', line)print(result)result = re.sub('#.*$', '', line)print(result)在第 4 行,搜索字符串 line,将与模式 ‘\d+’ 匹配的字符串替换为 ‘NUMBER’模式 ‘\d+’ 匹配多个连续的数字在第 6 行,搜索字符串 line,将与模式 ‘#.*$’ 匹配的字符串替换为 ‘’替换为空字符串,即删除匹配的字符串模式 ‘#.*$’ 匹配从字符 # 开始到到结尾的字符串,即行的注释程序输出结果:number = NUMBER # this is commentnumber = 123在第 1 行,将数字 123 替换为 NUMBER在第 1 行,将以 # 开始的注释删除

C 语言字符串练习

在 C 语言中字符串的应用比较多,所以在这里我们实现一个函数,函数功能是将一串给定的字符串中的大写字符全部转换为小写字符。

3. 字符类型

在 Kotlin 中字符用 Char 类型表示。并且不能像 Java 一样可以直接当作数字:fun testChar(char: Char) { if(char == 4) {...}//此处会提示类型不匹配的异常}字符的值用单引号括起来: '1'。 特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b、\n、\r、\'、\"、\\ 与 \$。 编码其他字符要用 Unicode 转义序列语法:'\uFF00'。虽然不能直接把它当作数字来用,但是我们可以通过decimalDigitValue函数将字符转换成数字,注意可空类型 Char? 类型会存在装箱操作fun decimalDigitValue(c: Char): Int { if (c !in '0'..'9') throw IllegalArgumentException("Out of range") return c.toInt() - '0'.toInt() // 显式转换为数字}

2.4 函数返回值

函数返回值利用 $? 来接收,在上述示例中我们将计算的结果利用 echo 命令打印出来,如果我们在后续的脚本中需要利用此函数计算的结果,就需要得到这个返回值,此刻就需要将计算的结果不仅仅是打印而是返回了,函数中返回利用 return 关键字,在函数调用完成后,我们利用 $? 来接受函数的返回值,例如将我们上面的示例改造成返回结构的函数。注意:shell 函数的返回值,只能是整形,并且在 0-257 之间,不能是字符串或其他形式。并且在调用方法和取得返回值之间,不能有任何操作,不然取不到 return 的值。[root@master func]# cat f1.sh #!/bin/bashfunction fsum() { echo "函数第一个参数为: ${1}" echo "函数第二个参数为: ${2}" echo "函数第三个参数为: ${3}" echo "函数的参数总数为: ${#}" echo "函数的参数总数为: ${@}" local sum=0 for num in ${@}; do let sum=${sum}+${num} done return $sum}fsum 10 20 1 2echo $?[root@master func]# bash f1.sh 函数第一个参数为: 10函数第二个参数为: 20函数第三个参数为: 1函数的参数总数为: 4函数的参数总数为: 10 20 1 233可以看到我们将在函数内部计算的数组之和,利用 return 作为返回,此刻在函数调用的时候,利用 $? 就可以拿到函数返回的值进一步处理。

3.1 将字符串转换为整数

>>> number = int('123')>>> number123函数 int(string) 将字符串 string 转换为整数

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

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

帮助反馈 APP下载

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

公众号

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