目录
第1关:读CSV文件
任务描述本关任务:了解不同的编码格式。
代码
第2关:清洗列名
任务描述本关任务:学会如何对列名进行清洗。
代码
第3关:清洗列名(续)
任务描述本关任务:继续清洗列名。
代码
第4关:将字符串列转换为数值列
代码
第5关:删除非数字字符
任务描述在上一个练习中,我们在ram列中确定了一个清晰的模式——所有的值都是整数,字符串末尾包含字符GB:
代码
第6关:将列转换为数字类型
代码
第7关:列的重命名
任务描述现在我们已经将列转换为数字类型,最后一步是对列进行重命名。这是一个可选步骤,如果非数字值包含有助于我们理解数据的信息,则可能会很有用。
代码
第8关:从字符串中提取数值
任务描述有时,从字符串中提取非数值是很有用的。本关任务:从字符串中提取数值。
代码
第9关:纠正错误值
任务描述如果您的数据是从网页上抓取的,或者在某个时候涉及到手动数据输入,您可能会得到不一致的值。本关任务:学习怎么纠正错误值。
代码
第10关:删除缺失值
任务描述本关任务:学会删除缺失值。
代码
第11关:填充缺失值
任务描述本关任务:学会填充缺失值。
代码
第12关:挑战:对字符串列进行清洗
任务描述本关任务:对字符串列进行清洗。
代码
相关知识
在这个实训中,我们将学习使用pandas来学习数据清理的基础知识,我们使用的数据是laptops.csv,这是一个包含1,300台笔记本电脑信息的CSV文件。CSV文件的前五行如下所示:
Manufacturer Model Name Category Screen Size Screen CPU RAM Storage GPU Operating System Operating System Version Weight Price (Euros)
0 Apple MacBook Pro Ultrabook 13.3" IPS Panel Retina Display 2560x1600 Intel Core i5 2.3GHz 8GB 128GB SSD Intel Iris Plus Graphics 640 macOS NaN 1.37kg 1339,69
1 Apple Macbook Air Ultrabook 13.3" 1440x900 Intel Core i5 1.8GHz 8GB 128GB Flash Storage Intel HD Graphics 6000 macOS NaN 1.34kg 898,94
2 HP 250 G6 Notebook 15.6" Full HD 1920x1080 Intel Core i5 7200U 2.5GHz 8GB 256GB SSD Intel HD Graphics 620 No OS NaN 1.86kg 575,00
3 Apple MacBook Pro Ultrabook 15.4" IPS Panel Retina Display 2880x1800 Intel Core i7 2.7GHz 16GB 512GB SSD AMD Radeon Pro 455 macOS NaN 1.83kg 2537,45
4 Apple MacBook Pro Ultrabook 13.3" IPS Panel Retina Display 2560x1600 Intel Core i5 3.1GHz 8GB 256GB SSD Intel Iris Plus Graphics 650 macOS NaN 1.37kg 1803,60
我们可以从将数据读入到pandas中开始。让我们看一下当我们使用pandas.read_csv()函数只有参数filename时会发生什么:
laptops = pd.read_csv("laptops.csv")
输出结果:
Traceback (most recent call last):
File "pandas/_libs/parsers.pyx" in pandas._libs.parsers.TextReader._convert_tokens
File "pandas/_libs/parsers.pyx" in pandas._libs.parsers.TextReader._convert_with_dtype
File "pandas/_libs/parsers.pyx" in pandas._libs.parsers.TextReader._string_convert
File "pandas/_libs/parsers.pyx" in pandas._libs.parsers._string_box_utf8
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 4: invalid continuation byte
我们得到一个错误!(错误消息已被缩短。)此错误与UTF-8相关,这是一种编码类型。计算机只能理解二进制的0和1,而编码是表示二进制字符的系统。
如果我们的文件有一个未知的编码,我们可以做的是尝试最常见的编码:
UTF-8
Latin-1 (也被称为ISO-8895-1)
Windows-1251
pandas.read_csv()函数有一个我们可以用来指定编码的参数encoding:
df = pd.read_csv("filename.csv", encoding="some_encoding")
由于pandas.read_csv()函数已尝试使用UTF-8读取文件失败,因此我们知道该文件未使用该格式进行编码。让我们在练习中尝试下一个最流行的编码。
编程要求
导入pandas库
使用pandas.read_csv()函数将laptops.csv文件读入到名为laptops的一个dataframe中。
使用字符串"Latin-1"指定编码。
使用DataFrame.info()方法显示有关laptops的信息。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确的数值,只有所有数据全部计算正确才能进入下一关。
#********** Begin **********#
import pandas as pd
laptops=pd.read_csv("laptops.csv",encoding="Latin-1")
laptops.info()
#********** End **********#
相关知识
下面是前一关的datafram.info()方法的输出:
class 'pandas.core.frame.DataFrame'
RangeIndex: 1303 entries, 0 to 1302
Data columns (total 13 columns):
Manufacturer 1303 non-null object
Model Name 1303 non-null object
Category 1303 non-null object
Screen Size 1303 non-null object
Screen 1303 non-null object
CPU 1303 non-null object
RAM 1303 non-null object
Storage 1303 non-null object
GPU 1303 non-null object
Operating System 1303 non-null object
Operating System Version 1133 non-null object
Weight 1303 non-null object
Price (Euros) 1303 non-null object
dtypes: object(13)
memory usage: 132.4+ KB
我们可以看到,每一列都表示为object类型,这表明它们是字符串而不是数字。另外,其中一列Operating System Version有空值。
列标签有各种大小写字母、空格和括号,这将使它们更难使用和阅读。一个显著的问题是" Storage"列名前面有一个空格。列标签的这些怪癖有时很难发现,因此从长远来看,从所有列名中删除额外的空格将为我们节省更多的工作。
我们可以使用DataFrame.columns属性访问dataframe的列。这将返回一个索引对象(一种特殊类型的NumPy ndarray),每列的标签如下:
print(laptops.columns)
输出结果:
Index(['Manufacturer', 'Model Name', 'Category', 'Screen Size', 'Screen',
'CPU', 'RAM', ' Storage', 'GPU', 'Operating System',
'Operating System Version', 'Weight', 'Price (Euros)'],
dtype='object')
我们不仅可以使用属性查看列标签,还可以为属性分配新的标签:
laptops_test = laptops.copy()
laptops_test.columns = ['A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M']
print(laptops_test.columns)
输出结果:
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'], dtype='object')
接下来,让我们使用DataFrame.columns属性从列名中删除空格。
编程要求
从每个列名的开头和结尾删除任何空格。
创建一个名为new_columns的空列表。
使用for循环使用DataFrame.columns属性迭代每个列名。在for循环体内:
使用str.strip()方法删除字符串开头和结尾的空格。
将更新后的列名附加到列表new_columns。
将更新后的列名赋值给DataFrame.columns属性。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确的数值,只有所有数据全部计算正确才能进入下一关。
import pandas as pd
laptops = pd.read_csv('laptops.csv', encoding='Latin-1')
#********** Begin **********#
# laptops.columns=['Manufacturer', 'Model Name', 'Category', 'Screen Size', 'Screen',
# 'CPU', 'RAM', 'Storage', 'GPU', 'Operating System',
# 'Operating System Version', 'Weight', 'Price (Euros)']
# print(laptops.columns)
new_columns=[]
for x in laptops.columns:
new_columns.append(x.strip())
laptops.columns=new_columns
print(laptops.columns)
#********** End **********#
相关知识
在上一关我们从列名中删除了空格。结果如下:
Index(['Manufacturer', 'Model Name', 'Category', 'Screen Size', 'Screen',
'CPU', 'RAM', 'Storage', 'GPU', 'Operating System',
'Operating System Version', 'Weight', 'Price (Euros)'],
dtype='object')
然而,列标签仍然有各种大小写字母,以及括号,这会使它们更难使用和阅读。让我们清洗列标签:
用下划线替换空格。
删除特殊字符。
使所有标签小写。
缩短长列名。
我们可以创建一个函数,该函数使用Python字符串方法来清洗列标签,然后再次使用循环将该函数应用于每个标签。让我们来看一个例子:
def clean_col(col):
col = col.strip()
col = col.replace("(","")
col = col.replace(")","")
col = col.lower()
return col
new_columns = []
for c in laptops.columns:
clean_c = clean_col(c)
new_columns.append(clean_c)
laptops.columns = new_columns
print(laptops.columns)
输出结果:
Index(['manufacturer', 'model name', 'category', 'screen size', 'screen',
'cpu', 'ram', 'storage', 'gpu', 'operating system',
'operating system version', 'weight', 'price euros'],
dtype='object')
我们的代码:
定义了一个函数,其中:
使用string.strip()方法删除字符串开头和结尾的空格。
使用string.replace()方法从字符串中删除括号。
使用string.lower()方法使字符串小写。
返回修改后的字符串。
使用循环将函数应用于索引对象中的每个项并将其赋值给DataFrame.columns属性。
打印DataFrame.columns属性新的值。 让我们使用这种技术来清洗dataframe中的列标签。
编程要求
定义一个函数,该函数接受一个字符串参数,并且:
删除字符串开始和结束处的空格。
用缩写os替换子字符串Operating System。
用下划线替换所有空格。
从字符串中移除括号。
使整个字符串小写。
返回修改后的字符串。
使用循环将函数应用于laptops的dataframe的DataFrame.columns属性中的每项。将结果赋值给DataFrame.columns属性。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确的数值,只有所有数据全部计算正确才能进入下一关。
import pandas as pd
laptops = pd.read_csv('laptops.csv', encoding='Latin-1')
#********** Begin **********#
new_columns=[]
for x in laptops.columns:
x=x.strip()
x=x.replace("Operating System","os")
x=x.replace(" ","_")
x=x.replace("(","")
x=x.replace(")","")
x=x.lower()
new_columns.append(x)
laptops.columns=new_columns
print(laptops.columns)
#********** End **********#
任务描述
本关任务:将字符串列转换为数值列。
相关知识
我们在前面观察到,所有13列都具有对象dtype,这意味着它们被存储为字符串。让我们看看我们的一些列的前几行:
print(laptops.iloc[:5,2:5])
输出结果:
_ category screen_size screen
0 Ultrabook 13.3" IPS Panel Retina Display 2560x1600
1 Ultrabook 13.3" 1440x900
2 Notebook 15.6" Full HD 1920x1080
3 Ultrabook 15.4" IPS Panel Retina Display 2880x1800
4 Ultrabook 13.3" IPS Panel Retina Display 2560x1600
在这三列中,我们有三种不同类型的文本数据:
category:纯文本数据——没有数值。
screen_size:由于"字符而存储为文本数据的数值数据。
screen:纯文本数据与数字数据的组合。
因为s