Pandas08--文本数据
目录
- 1 str对象
- 1.1 str基础
- 1.2 string类型
- 2 正则表达式基础
- 3 文本处理的五类操作
- 3.1 拆分
- 3.2 合并
- 3.3 匹配
- 3.4 替换
- 3.5 提取
- 4 常用字符串函数
- 4.1 字母型函数
- 4.2 数值型函数
- 4.3 统计型函数
- 4.4 格式型函数
- 5 练习
- 5.1 房屋信息数据集
- 5.2 《权力的游戏》剧本数据集
1 str对象
1.1 str基础
- str对象的设计意图
- 作用:
str
对象是定义在Index 或 Series
上的属性,专门用于逐元素处理文本内容,其内部定义了大量方法。 - 使用:对一个序列进行文本处理,首先需要获取其
str
对象。
注意:在
Python
标准库中也有 str 模块,为了使用上的便利,有许多函数的用法pandas
照搬了它的设计- 【例子】字母转为大写的操作
var = 'abcd' str.upper(var) # Python内置str模块 # 'ABCD's=pd.Series(['abcd','efg','hi']) s.str.upper() # pandas中str对象上的upper方法 ''' 0 ABCD 1 EFG 2 HI dtype: object '''
- 作用:
- []索引器
- 作用: 对于
str
对象而言,可理解为其对字符串进行了序列化的操作
注意:如果超出范围则返回缺失值
- 【例子】通过 [] 取出某个位置的元素
var[0] # 'a' var[-1:0:-2] # 通过切片得到子串 # 'db'
s.str[0] ''' 0 a 1 e 2 h dtype: object ''' s.str[-1: 0: -2] ''' 0 db 1 g 2 i dtype: object ''' s.str[2] ''' 0 c 1 g 2 NaN dtype: object '''
- 作用: 对于
1.2 string类型
string
和object
:在string
未引入之前,所有的字符串类型都以object
类型的Series
进行存储,但object
类型只应该存储混合类型,比如同时存储字符串、字典、列表等,因此字符串要有自己的数据类型,因此引入string
类型。
因此,绝大多数对于object
和string
类型的序列使用str
对象方法产生的结果是一致,除了下面提到的两点- 区别一:
- 区别点: 对于一个可迭代对象,
string
类型的str
对象和object
类型的str
对象返回结果可能是不同的 - 使用
str
属性:首先,应当尽量保证每一个序列中的值都是字符串的情况下才使用str
属性,但这并不是必须的,其必要条件是序列中至少有一个可迭代(Iterable)对象,包括但不限于字符串、字典、列表。 - 【例子】
s = pd.Series([{1: 'temp_1', 2: 'temp_2'}, ['a', 'b'], 0.5, 'my_string']) s.str[1] # 按每个元素进行索引 ''' 0 temp_1 1 b 2 NaN 3 y dtype: object ''' s.astype('string').str[1] # 把每个元素转为字符串 ''' 0 1 1 ' 2 . 3 y dtype: string '''
分析:
- 当序列类型为
object
时,是对于每一个元素进行[]
索引,因此对于字典而言,返回temp_1
字符串,对于列表则返回第二个值,而第三个为不可迭代对象,返回缺失值,第四个是对字符串进行[]
索引。 - 而
string
类型的str
对象先把整个元素转为字面意义的字符串,例如对于列表而言,第一个元素即 “{
“,而对于最后一个字符串元素而言,恰好转化前后的表示方法一致,因此结果和object
类型一致。
- 区别点: 对于一个可迭代对象,
- 区别二:
- 区别点: string 类型是 Nullable 类型,但 object 不是
- 导致的结果:
string
类型的序列,如果调用的str
方法返回值为整数Series
和布尔Series
时,其分别对应的dtype
是In
和boolean
的Nullable
类型
object
类型则会分别返回int/float
和bool/object
,取决于缺失值的存在与否
同时,字符串的比较操作,也具有相似的特性,string
返回Nullable
类型,但object
不会。
-【例子】
s = pd.Series(['a'])s.str.len() s.astype('string').str.len() ''' 0 1 dtype: Int64 '''s = pd.Series(['a', np.nan]) # 带有缺失值 s.str.len() ''' 0 1.0 1 NaN dtype: float64 ''' s.astype('string').str.len() ''' 0 1 1 <NA> dtype: Int64 '''s == 'a' ''' 0 True 1 False dtype: bool '''s.astype('string') == 'a' ''' 0 True 1 <NA> dtype: boolean '''
注意:对于全体元素为数值类型的序列,即使其类型为
object
或者category
也不允许直接使用str
属性。如果需要把数字当成string
类型处理,可以使用astype
强制转换为string
类型的Series
s = pd.Series([12, 345, 6789]) s.astype('string').str[1] ''' 0 2 1 4 2 7 dtype: string '''
2 正则表达式基础
- 正则表达式:正则表达式是一种按照某种正则模式,从左到右匹配字符串中内容的一种工具。
- 一般字符的匹配:对于一般的字符而言,它可以找到其所在的位置
- 函数:使用了
python
中re
模块的findall
函数来匹配所有出现过但不重叠的模式,第一个参数是正则表达式,第二个参数是待匹配的字符串。 - 【例子】在下面的字符串中找出 apple
import re re.findall(r'Apple', 'Apple! This Is an Apple!') # ['Apple', 'Apple']
- 函数:使用了
- 元字符基础:
元字符 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符 |
[ ] | 字符类,匹配方括号中包含的任意字符 |
[^ ] | 否定字符类,匹配方括号中不包含的任意字符 |
* | 匹配前面的子表达式零次或多次 |
+ | 匹配前面的子表达式一次或多次 |
? | 匹配前面的子表达式零次或一次 |
{n,m} | 花括号,匹配前面字符至少 n 次,但是不超过 m 次 |
(xyz) | 字符组,按照确切的顺序匹配字符xyz |
| | 分支结构,匹配符号之前的字符或后面的字符 |
\ | 转义符,它可以还原元字符原来的含义 |
^ | 匹配行的开始 |
$ | 匹配行的结束 |
re.findall(r'.', 'abc') # 匹配除换行符以外的任意字符# ['a', 'b', 'c']re.findall(r'[ac]', 'abc') # 匹配方括号中包含的任意字符# ['a', 'c']re.findall(r'[^ac]', 'abc') # 匹配方括号包含的以外的任意字符# ['b']re.findall(r'[ab]{2}', 'aaaabbbb') # {n}指匹配n次# ['aa', 'aa', 'bb', 'bb']re.findall(r'aaa|bbb', 'aaaabbbb') # 匹配符号之前的字符或后面的字符# ['aaa', 'bbb']re.findall(r'a\\?|a\*', 'aa?a*a') # a\\?表示a与零个或一个\# ['a?', 'a*']
分析:'a\\?|a\*',\\?表示零个或一个\,因此a\\?表示a与零个或一个\;
然后这个每次匹配的时候找到一个就终止,所以a*虽然存在但是被a已经匹配,所以屏蔽掉了
简写字符集:
- 作用:正则表达式中还有一类简写字符集,其等价于一组字符的集合
- 种类:
写 描述 \w 匹配所有字母、数字、下划线: [a-z A-Z 0-9_ ] \W 匹配非字母和数字的字符: [^\w] \d 匹配数字: [0-9] \D 匹配非数字: [^\d] \s 匹配空格符: [\t \n \f \r \p {Z}] \S 匹配非空格符: [^\s] \B 匹配一组非空字符开头或结尾的位置,不代表具体字符 - 【例子】
re.findall(r'.s', 'Apple! This Is an Apple!') # ['is', 'Is'] re.findall(r'\w{2}', '09 8? 7w c_ 9q p@') # {2}代表匹配两个字符的 # ['09', '7w', 'c_', '9q']re.findall(r'\w\W\B', '09 8? 7w c_ 9q p@') # ['8?', 'p@']re.findall('.\s.', 'Constant dropping wears the stone.') # ['t d', 'g w', 's t', 'e s'] ''' 分析: .\s.:前面一个字符 + 空格 + 后面一个字符 '''re.findall('上海市(.{2,3}区)(.{2,3}路)(\d+号)','上海市黄浦区方浜中路249号 上海市宝山区密山路5号') # [('黄浦区', '方浜中路', '249号'), ('宝山区', '密山路', '5号')] ''' 分析:.{2,3}:先找到2个的字符,然后最多连续不超过3次 \d+:“+”前面的字符至少出现一次 '''
3 文本处理的五类操作
3.1 拆分
str.split
函数:str.split
能够把字符串的列进行拆分,其中第一个参数为正则表达式,- 可选参数:包括从左到右的最大拆分次数
n
,是否展开为多个列expand
。 - 【例子】
s = pd.Series(['上海市黄浦区方浜中路249号', '上海市宝山区密山路5号']) s.str.split('[市区路]') ''' 0 [上海, 黄浦, 方浜中, 249号] 1 [上海, 宝山, 密山, 5号] dtype: object ''' s.str.split('[市区路]', n=2, expand=True) # n=2,从左到右只能拆分两次,即只能按市和区拆分,用不到路 '''0 1 2 0 上海 黄浦 方浜中路249号 1 上海 宝山 密山路5号 '''
- 可选参数:包括从左到右的最大拆分次数
str.rsplit
函数:区别在于使用n
参数的时候是从右到左限制最大拆分次数。目前版本rsplit
暂时无法使用
3.2 合并
str.join
函数:表示用某个连接符把Series
中的字符串列表连接起来,如果列表中出现了非字符串元素则返回缺失值- 【例子】
s = pd.Series([['a','b'], [1, 'a'], [['a', 'b'], 'c']]) s.str.join('-') ''' 0 a-b 1 NaN 2 NaN dtype: object '''
str.cat
函数:用于合并两个序列- 主要参数:为连接符
sep
、连接形式join
以及缺失值替代符号na_rep
,其中连接形式默认为以索引为键的左连接。 - 【例子】
s1 = pd.Series(['a','b']) s2 = pd.Series(['cat','dog']) s1.str.cat(s2,sep='-') ''' 0 a-cat 1 b-dog dtype: object ''' s2.index = [1, 2] s1.str.cat(s2, sep='-', na_rep='?', join='outer') ''' 0 a-? 1 b-cat 2 ?-dog dtype: object '''
- 主要参数:为连接符
3.3 匹配
str.contains
函数:返回了每个字符串是否包含正则模式的布尔序列- 【例子】
s = pd.Series(['my cat', 'he is fat', 'railway station']) s.str.contains('\s\wat') # 匹配空格符,字母和at ''' 0 True 1 True 2 False dtype: bool '''
str.startswith
和str.endswith
: 返回了每个字符串以给定模式为开始和结束的布尔序列,它们都不支持正则表达式- 【例子】
s.str.startswith('my') ''' 0 True 1 False 2 False dtype: bool ''' s.str.endswith('t') ''' 0 True 1 True 2 False dtype: bool '''
str.match
函数:用正则表达式来检测开始或结束字符串的模式,其返回了每个字符串起始处是否符合给定正则模式的布尔序列- 【例子】
s.str.match('m|h') ''' 0 True 1 True 2 False dtype: bool ''' s.str[::-1].str.match('ta[f|g]|n') # 反转后匹配 0 False 1 True 2 True dtype: bool
- 【例子】用
str.contains
的正则中使用^
和$
来实现
s.str.contains('^[m|h]') ''' 0 True 1 True 2 False dtype: bool ''' s.str.contains('[f|g]at|n$') ''' 0 False 1 True 2 True dtype: bool '''
str.find
与str.rfind
:返回索引的匹配函数,其分别返回从左到右和从右到左第一次匹配的位置的索引,未找到则返回-1。- 注意:两个函数不支持正则匹配,只能用于字符子串的匹配
- 【例子】
s = pd.Series(['This is an apple. That is not an apple.']) s.str.find('apple') ''' 0 11 dtype: int64 ''' s.str.rfind('apple') ''' 0 33 dtype: int64 '''
3.4 替换
str.replace
函数:str.replace
和replace
并不是一个函数,在使用字符串替换时应当使用前者。- 【例子】
s = pd.Series(['a_1_b','c_?']) s.str.replace('\d|\?', 'new', regex=True) # 替换数字或? ''' 0 a_new_b 1 c_new dtype: object '''
- 对不同部分进行有差别的替换:利用 子组 的方法,并且此时可以通过传入自定义的替换函数来分别进行处理,注意
group(k)
代表匹配到的第k
个子组(圆括号之间的内容)
例子:参考例子
3.5 提取
- 提取:提取既可以认为是一种返回具体元素(而不是布尔值或元素对应的索引位置)的匹配操作,也可以认为是一种特殊的拆分操作。
str.extract
函数:- 【例子】
pat = '(\w+市)(\w+区)(\w+路)(\d+号)' s.str.extract(pat) '''0 1 2 3 0 上海市 黄浦区 方浜中路 249号 1 上海市 宝山区 密山路 5号 2 北京市 昌平区 北农路 2号 '''
- 通过子组的命名,可以直接对新生成
DataFrame
的列命名:
pat = '(?P<市名>\w+市)(?P<区名>\w+区)(?P<路名>\w+路)(?P<编号>\d+号)' s.str.extract(pat) '''市名 区名 路名 编号 0 上海市 黄浦区 方浜中路 249号 1 上海市 宝山区 密山路 5号 2 北京市 昌平区 北农路 2号 '''
str.extractall
函数:不同于str.extract
只匹配一次,它会把所有符合条件的模式全部匹配出来,如果存在多个结果,则以多级索引的方式存储- 【例子】
s = pd.Series(['A135T15,A26S5','B674S2,B25T6'], index = ['my_A','my_B']) pat = '[A|B](\d+)[T|S](\d+)' s.str.extractall(pat) '''0 1match my_A 0 135 151 26 5 my_B 0 674 21 25 6 ''' pat_with_name = '[A|B](?P<name1>\d+)[T|S](?P<name2>\d+)' s.str.extractall(pat_with_name) '''name1 name2match my_A 0 135 151 26 5 my_B 0 674 21 25 6 '''
str.findall
函数:功能类似于str.extractall
,str.findall
把结果存入列表中,而后者处理为多级索引,每个行只对应一组匹配,而不是把所有匹配组合构成列表- 【例子】
s.str.findall(pat) ''' my_A [(135, 15), (26, 5)] my_B [(674, 2), (25, 6)] dtype: object '''
4 常用字符串函数
4.1 字母型函数
- ·upper, lower, title, capitalize, swapcase· 这五个函数主要用于字母的大小写转化
- 【例子】
s = pd.Series(['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe']) s.str.lower() ''' 0 lower 1 capitals 2 this is a sentence 3 swapcase dtype: object ''' s.str.title() ''' 0 Lower 1 Capitals 2 This Is A Sentence 3 Swapcase dtype: object '''
4.2 数值型函数
pd.to_numeric
函数:虽然不是str
对象上的方法,但是能够对字符格式的数值进行快速转换和筛选- 参数:
errors
和downcast
分别代表了非数值的处理模式和转换类型 errors
:有三种errors
选项,raise, coerce, ignore
分别表示直接报错、设为缺失以及保持原来的字符串- 【例子】
s = pd.Series(['1', '2.2', '2e', '??', '-2.1', '0']) pd.to_numeric(s, errors='ignore') ''' 0 1 1 2.2 2 2e 3 ?? 4 -2.1 5 0 dtype: object '''
- 参数:
- 在数据清洗时,可以利用
coerce
的设定,快速查看非数值型的行s[pd.to_numeric(s, errors='coerce').isna()] ''' 2 2e 3 ?? dtype: object '''
4.3 统计型函数
count 和 len
函数:分别是返回出现正则模式的次数和字符串的长度- 【例子】
s = pd.Series(['cat rat fat at', 'get feed sheet heat']) s.str.count('[r|f]at|ee') ''' 0 2 1 2 dtype: int64 ''' s.str.len() ''' 0 14 1 19 dtype: int64 '''
4.4 格式型函数
- 分类:格式型函数主要分为两类,第一种是除空型,第二种时填充型。
- 除空型函数:一共有三种,它们分别是
strip, rstrip, lstrip
,分别代表去除两侧空格、右侧空格和左侧空格。- 【例子】这些函数在数据清洗时是有用的,特别是列名含有非法空格的时候
my_index = pd.Index([' col1', 'col2 ', ' col3 ']) my_index.str.strip().str.len() # Int64Index([4, 4, 4], dtype='int64') my_index.str.rstrip().str.len() # Int64Index([5, 4, 5], dtype='int64') my_index.str.lstrip().str.len() # Int64Index([4, 5, 5], dtype='int64')
- 填充型函数:
pad
是最灵活的,它可以选定字符串长度、填充的方向和填充内容- 【例子】
s = pd.Series(['a','b','c']) s.str.pad(5,'left','*') ''' 0 ****a 1 ****b 2 ****c dtype: object ''' s.str.pad(5,'both','*') ''' 0 **a** 1 **b** 2 **c** dtype: object '''
【例子】分别用
rjust, ljust, center
来等效完成,需要注意ljust
是指右侧填充而不是左侧填充s.str.rjust(5, '*') s.str.center(5, '*')
5 练习
5.1 房屋信息数据集
现有一份房屋信息数据集如下:
In [114]: df = pd.read_excel('data/house_info.xls', usecols=[.....: 'floor','year','area','price']).....: In [115]: df.head(3)
Out[115]: us floor year area price
0 高层(共6层) 1986年建 58.23㎡ 155万
1 中层(共20层) 2020年建 88㎡ 155万
2 低层(共28层) 2010年建 89.33㎡ 365万
1.将 year 列改为整数年份存储。
- 答案:
df.year = pd.to_numeric(df.year.str[:-2]).astype('Int64') df.head(3) '''floor year area price 0 高层(共6层) 1986 58.23㎡ 155万 1 中层(共20层) 2020 88㎡ 155万 2 低层(共28层) 2010 89.33㎡ 365万 '''
2.将 floor 列替换为 Level, Highest 两列,其中的元素分别为 string 类型的层类别(高层、中层、低层)与整数类型的最高层数。
- 答案:
pat = '(\w层)(共(\d+)层)' # 正则表达式 new_cols = df.floor.str.extract(pat).rename(columns={0:'Level', 1:'Highest'}) df = pd.concat([df.drop(columns=['floor']), new_cols], 1) ''' year area price Level Highest 0 1986 58.23㎡ 155万 高层 6 1 2020 88㎡ 155万 中层 20 2 2010 89.33㎡ 365万 低层 28 '''
3.计算房屋每平米的均价 avg_price ,以 ***元/平米 的格式存储到表中,其中 *** 为整数。
- 答案:
s_area = pd.to_numeric(df.area.str[:-1]) s_price = pd.to_numeric(df.price.str[:-1]) df['avg_price'] = ((s_price/s_area)*10000).astype('int').astype('string') + '元/平米' df.head(3) '''year area price Level Highest avg_price 0 1986 58.23㎡ 155万 高层 6 26618元/平米 1 2020 88㎡ 155万 中层 20 17613元/平米 2 2010 89.33㎡ 365万 低层 28 40859元/平米 '''
参考答案
5.2 《权力的游戏》剧本数据集
现有一份权力的游戏剧本数据集如下:
In [116]: df = pd.read_csv('data/script.csv')In [117]: df.head(3)
Out[117]: Release Date Season Episode Episode Title Name Sentence
0 2011-04-17 Season 1 Episode 1 Winter is Coming waymar royce What do you expect? They're savages. One lot s...
1 2011-04-17 Season 1 Episode 1 Winter is Coming will I've never seen wildlings do a thing like this...
2 2011-04-17 Season 1 Episode 1 Winter is Coming waymar royce
1.计算每一个 Episode 的台词条数。
- 答案:
df = pd.read_csv('data/script.csv') df.columns = df.columns.str.strip() df.groupby(['Season', 'Episode'])['Sentence'].count().head() ''' Season Episode Season 1 Episode 1 327Episode 10 266Episode 2 283Episode 3 353Episode 4 404 Name: Sentence, dtype: int64 '''
2.以空格为单词的分割符号,请求出单句台词平均单词量最多的前五个人。
- 答案:
df.set_index('Name').Sentence.str.split().str.len().groupby('Name').mean().sort_values(ascending=False).head() ''' Name male singer 109.000000 slave owner 77.000000 manderly 62.000000 lollys stokeworth 62.000000 dothraki matron 56.666667 Name: Sentence, dtype: float64 '''
3.若某人的台词中含有问号,那么下一个说台词的人即为回答者。若上一人台词中含有 n 个问号,则认为回答者回答了 n 个问题,请求出回答最多问题的前五个人。
- 答案:
s = pd.Series(df.Sentence.values, index=df.Name.shift(-1)) s.str.count('\?').groupby('Name').sum().sort_values(ascending=False).head( ''' Name tyrion lannister 527 jon snow 374 jaime lannister 283 arya stark 265 cersei lannister 246 dtype: int64 '''
参考答案
Pandas08--文本数据相关推荐
- nlp文本数据增强_如何使用Texthero为您的NLP项目准备基于文本的数据集
nlp文本数据增强 Natural Language Processing (NLP) is one of the most important fields of study and researc ...
- 如何用Pandas处理文本数据?
↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过Datawhale干货 作者:耿远昊,Datawhale成员,华东师范大学 文本数据是指不能参与算 ...
- python文本数据处理_从 App 描述介绍文字中发掘 Python 文本数据预处理实例
本文为 AI 研习社编译的技术博客,原标题 What App Descriptions Tell Us: Text Data Preprocessing in Python,作者为 Finn Qiao ...
- R语言构建文本分类模型:文本数据预处理、构建词袋模型(bag of words)、构建xgboost文本分类模型、基于自定义函数构建xgboost文本分类模型
R语言构建文本分类模型:文本数据预处理.构建词袋模型(bag of words).构建xgboost文本分类模型.基于自定义函数构建xgboost文本分类模型 目录
- R语言构建文本分类模型并使用LIME进行模型解释实战:文本数据预处理、构建词袋模型、构建xgboost文本分类模型、基于文本训练数据以及模型构建LIME解释器解释多个测试语料的预测结果并可视化
R语言构建文本分类模型并使用LIME进行模型解释实战:文本数据预处理.构建词袋模型.构建xgboost文本分类模型.基于文本训练数据以及模型构建LIME解释器解释多个测试语料的预测结果并可视化 目录
- R语言构建文本分类模型:文本数据预处理、构建词袋模型(bag of words)、构建xgboost文本分类模型、xgboost模型预测推理并使用混淆矩阵评估模型、可视化模型预测的概率分布
R语言构建文本分类模型:文本数据预处理.构建词袋模型(bag of words).构建xgboost文本分类模型.xgboost模型预测推理并使用混淆矩阵评估模型.可视化模型预测的概率分布 目录
- 8W+文本数据,全景式展现中国教育发展情况
来源:兴富同学 本文约5800字,建议阅读8分钟. 本文介绍了通过文本数据分析,全方面展示了中国教育发展的情况. 前面使用爬虫的方法动态获取了教育资讯,完成之后就会很自然就会想,能不能把所有的文本都获 ...
- 独家 | 文本数据探索性数据分析结合可视化和NLP产生见解(附代码)
作者:Susan Li 翻译:吴金笛 校对:和中华 本文约5000字,建议阅读12分钟. 本文使用电子商务的评价数据集作为实例来介绍基于文本数据特征的数据分析和可视化. 作为数据科学家或NLP专家,可 ...
- 基于深度学习的文本数据特征提取方法之Glove和FastText
2019-12-03 20:49:51 作者:Dipanjan (DJ) Sarkar 编译:ronghuaiyang 导读 今天接着昨天的内容,给大家介绍Glove模型和FastText模型,以及得 ...
- 机器学习实战:朴素贝叶斯算法在新闻文本数据上的分类表现
https://www.toutiao.com/a6647102437532369421/ 2019-01-17 08:01:00 大家好,今天跟大家学习一下通过sklearn的朴素贝叶斯模型实战.前 ...
最新文章
- Laravel Predis Error while reading line from the server.
- erlang supervisor simple_one_for_one实例
- printf()详解
- html5的form如何使用方法,HTML5 FormData方法介绍
- 上厕所时间超长也能被开除?法院:超出正常生理需求范围!
- java ssh 学习_初学Java ssh之Spring 第三篇
- PHP - Smarty模板引擎 - Download下载 - 2.6.22
- AX9000利用docker实现迅雷远程下载
- Codeforces 235C. Cyclical Quest 后缀自动机
- PID控制器原理详解
- 解决win10访问xp服务器共享文件出现smb1问题
- JAVA 分片上传、断点下载场景
- 5款超级无敌好用的电脑软件 建议收藏!
- 【转】小船过河问题(贪心)
- c语言原子操作实例,多CPU上的原子操作
- DataFrame写入mysql时报错Duplicate entry ‘...‘ for key ‘PRIMARY
- 生于1999年的11家互联网公司:为何唯独阿里巴巴化茧成蝶?
- Vue经典实例之table表格奇偶行不同颜色、鼠标移入变色、点击变色,一看就明白
- 每日3词 2021-03-11 【name】【attribute】【value】
- cefsharp 带cookie打开网址
热门文章
- 安全报告处理 HCL AppScan Standard
- 计算机开机黑屏风扇转,电脑风扇转但是开不了机怎么办_电脑风扇转但是黑屏...
- OpenShift免费空间申请使用教程
- 前端基础—— 选择器 、css
- wp网站,wordpress网站搭建,wp网站建设教程
- GeoServer中使用SLD样式
- 【PTA-乙级】1019 - 数字黑洞(4种解法)(C/C++)
- 黑苹果E430c, 安装过程
- python语言接收信息的内置函数_Python这7个好用内置函数!
- 线形设计matlab,立交匝道平面线形优化设计及MATLAB的应用