本文概述
- Pandas
- 加载数据中
- 缺失数据
- 数据转换
- 现在怎么办?
加载数据, 清理数据(删除不必要的数据或错误的数据), 转换数据格式和重新排列数据是数据准备步骤中涉及的各个步骤。在本教程中, 你将使用Python的Pandas库进行数据准备。
确保你了解Pandas DataFrame, Series等概念, 因为你将在本教程中大量阅读它。你可以在srcmini的Pandas教程中进一步了解Pandas。
在本教程中:
- 首先, 你将简要介绍Pandas-使用的库。
- 然后, 你将加载数据。
- 接下来, 你将看到丢失的数据是什么以及如何使用它们。你将看到如何处理丢失的数据以及填充丢失的数据的方法。
- 然后, 你将学习一些数据转换技巧:替换值, 连接Pandas系列, 使用地图函数向数据集中添加知识, 离散化连续数据, 最后涉及虚拟变量和一键编码。
让我们从对Pandas的简短介绍开始…
Pandas Pandas是为Python编写的软件库。它在数据科学界非常有名, 因为它提供了功能强大, 表现力强且灵活的数据结构, 使数据操作, 分析变得容易并且可以免费获得。此外, 如果你有特定的新用例, 甚至可以在Python邮件列表之一或pandas GitHub站点上共享它-实际上, 这是现实世界中驱动pandas的大多数功能的方式用例。
要获得有关Pandas的出色介绍, 请务必查看srcmini的Pandas基金会课程。它是非常互动的, 第一章是免费的!
要使用pandas库, 你需要先将其导入。只需在你的python控制台中输入以下内容即可:
import pandas as pd
加载数据中 数据准备的第一步是……好吧, 获取一些数据。如果你有.csv文件, 则可以使用pandas中的.read_csv()函数轻松地将其加载到系统中。然后可以输入:
数据= pd.read_csv(‘ path_to_file.csv’ )
但是, 对于本教程, 你将使用动态创建的一些较小的, 易于理解的DataFrame和Series。
缺失数据 处理丢失的数据
这是数据分析世界中普遍存在的问题。
文章图片
由于多种原因, 数据集中可能会丢失数据:用户/数据收集应用程序未添加特定字段的数据, 手动传输时数据丢失, 编程错误等。有时, 弄清原因是必不可少的因为这会影响你处理此类数据的方式。但这将在本教程后面讨论。现在, 让我们集中讨论如果缺少数据该怎么办…
对于数字数据, Pandas使用浮点值NaN(非数字)表示丢失的数据。它是库Numpy下定义的唯一值, 因此我们也需要导入它。由于计算速度和便利性的原因, NaN是默认的缺失值标记。从某种意义上来说, 这是一个前哨值, 可以使用Pandas中的函数轻松检测和使用伪数据或标志值。
文章图片
让我们玩一些数据…
import numpy as np# Creating a pandas series
data = http://www.srcmini.com/pd.Series([0, 1, 2, 3, 4, 5, np.nan, 6, 7, 8])# To check if and what index in the dataset contains null value
data.isnull()
0False
1False
2False
3False
4False
5False
6True
7False
8False
9False
dtype: bool
上面, 我们使用了函数isull()返回布尔值true或false。是的, 当该特定索引处的数据实际上丢失或为NaN时。相反的是notnull()函数。
# To check where the dataset does not contain null value - opposite of isnull()
data.notnull()
0True
1True
2True
3True
4True
5True
6False
7True
8True
9True
dtype: bool
此外, 我们可以使用dropna()函数过滤掉丢失的数据并删除null(缺失)值, 并仅查看非null值。但是, NaN值并没有真正删除, 仍然可以在原始数据集中找到。
# Will not show the index 6 cause it contains null (NaN) value
data.dropna()
00.0
11.0
22.0
33.0
44.0
55.0
76.0
87.0
98.0
dtype: float64
data
00.0
11.0
22.0
33.0
44.0
55.0
6NaN
76.0
87.0
98.0
dtype: float64
要真正” 删除” 或删除NaN值, 你可以执行的操作是存储新数据集(不使用NaN), 以使原始数据系列不被篡改或就地放置删除。 inplace参数的默认值为false。
not_null_data = http://www.srcmini.com/data.dropna()
not_null_data
00.0
11.0
22.0
33.0
44.0
55.0
76.0
87.0
98.0
dtype: float64
# Drop the 6th index in the original 'data' since it has a NaN place
data.dropna(inplace = True)
data
00.0
11.0
22.0
33.0
44.0
55.0
76.0
87.0
98.0
dtype: float64
但是, 数据框可能更复杂并且为2维, 这意味着它们包含行和列。Pandas还有你覆盖…
# Creating a dataframe with 4 rows and 4 columns (4*4 matrix)
data_dim = pd.DataFrame([[1, 2, 3, np.nan], [4, 5, np.nan, np.nan], [7, np.nan, np.nan, np.nan], [np.nan, np.nan, np.nan, np.nan]])
data_dim
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | NaN | NaN |
2 | 7.0 | NaN | NaN | NaN |
3 | NaN | NaN | NaN | NaN |
# Drop all rows and columns containing NaN value
data_dim.dropna()
0 | 1 | 2 | 3 |
---|
# Drop all rows and columns containing entirely of NaN value
data_dim.dropna(how = 'all')
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | NaN | NaN |
2 | 7.0 | NaN | NaN | NaN |
# Drop only columns that contain entirely NaN value
# Default is 0 - which signifies rows
data_dim.dropna(axis = 1, how = 'all')
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | 2.0 | 3.0 |
1 | 4.0 | 5.0 | NaN |
2 | 7.0 | NaN | NaN |
3 | NaN | NaN | NaN |
# Drop all columns that have more than 2 NaN values
data_dim.dropna(axis = 1, thresh = 2)
0 | 1 | |
---|---|---|
0 | 1.0 | 2.0 |
1 | 4.0 | 5.0 |
2 | 7.0 | NaN |
3 | NaN | NaN |
# Drop all rows that have more than 2 NaN values
data_dim.dropna(thresh = 2)
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | NaN | NaN |
填写缺失数据
要替换或” 填充” 空数据, 可以使用fillna()函数。例如, 让我们尝试使用与上述相同的数据集, 并尝试用0填充NaN值。
# Check what the dataset looks like again
data_dim
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | NaN | NaN |
2 | 7.0 | NaN | NaN | NaN |
3 | NaN | NaN | NaN | NaN |
# Fill the NaN values with 0
data_dim_fill = data_dim.fillna(0)
data_dim_fill
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | 0.0 |
1 | 4.0 | 5.0 | 0.0 | 0.0 |
2 | 7.0 | 0.0 | 0.0 | 0.0 |
3 | 0.0 | 0.0 | 0.0 | 0.0 |
# Pass a dictionary to use differnt values for each column
data_dim_fill = data_dim.fillna({0: 0, 1: 8, 2: 9, 3: 10})
data_dim_fill
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | 10.0 |
1 | 4.0 | 5.0 | 9.0 | 10.0 |
2 | 7.0 | 8.0 | 9.0 | 10.0 |
3 | 0.0 | 8.0 | 9.0 | 10.0 |
# Pass method to determine how to fill-up the column - forward here
data_dim_fill = data_dim.fillna(method='ffill')
data_dim_fill
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | 3.0 | NaN |
2 | 7.0 | 5.0 | 3.0 | NaN |
3 | 7.0 | 5.0 | 3.0 | NaN |
# Pass method to determine how to fill-up the column - forward here
data_dim_fill = data_dim.fillna(method='ffill', limit = 2)
data_dim_fill
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | 3.0 | NaN |
2 | 7.0 | 5.0 | 3.0 | NaN |
3 | 7.0 | 5.0 | NaN | NaN |
# Pass method to determine how to fill-up the row - forward here
data_dim_fill = data_dim.fillna(axis = 1, method='ffill')
data_dim_fill
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | 3.0 |
1 | 4.0 | 5.0 | 5.0 | 5.0 |
2 | 7.0 | 7.0 | 7.0 | 7.0 |
3 | NaN | NaN | NaN | NaN |
# Check the data_dim dataset
data_dim
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | NaN | NaN |
2 | 7.0 | NaN | NaN | NaN |
3 | NaN | NaN | NaN | NaN |
# Fill the NaN value with mean values in the corresponding column
data_dim_fill = data_dim.fillna(data_dim.mean())
data_dim_fill
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 2.0 | 3.0 | NaN |
1 | 4.0 | 5.0 | 3.0 | NaN |
2 | 7.0 | 3.5 | 3.0 | NaN |
3 | 4.0 | 3.5 | 3.0 | NaN |
到目前为止, 你只处理了缺失数据(NaN), 但是在某些情况下, 你可能希望将非空值替换为其他值。或者, 可能将空值记录为随机数, 因此需要将其处理为NaN而不是数字。这是replace()函数派上用场的地方…
这次我们创建一个不同的数据集。
data = http://www.srcmini.com/pd.Series([1, 2, -99, 4, 5, -99, 7, 8, -99])
data
01
12
2-99
34
45
5-99
67
78
8-99
dtype: int64
# Replace the placeholder -99 as NaN
data.replace(-99, np.nan)
00.0
11.0
22.0
33.0
44.0
55.0
76.0
87.0
98.0
dtype: float64
你将不再看到-99, 因为它已被NaN取代, 因此未显示。同样, 你可以传递多个要替换的值。为此, 我们将创建另一个系列, 然后将原始数据系列与新系列连接起来, 然后应用多值替换功能。
串联Pandas系列
为此, 我们可以在pandas中使用concat()函数。要在应用串联后继续建立索引, 可以向其传递ignore_index = True参数。
# Create a new Series
new_data = http://www.srcmini.com/pd.Series([-100, 11, 12, 13])
combined_series = pd.concat([data, new_data], ignore_index = True)
combined_series
01
12
2-99
34
45
5-99
67
78
8-99
9-100
1011
1112
1213
dtype: int64
# Let's replace -99 and -100 as NaN in the new combined_series
data_replaced = combined_series.replace([-99, -100], np.nan)
data_replaced
01.0
12.0
2NaN
34.0
45.0
5NaN
67.0
78.0
8NaN
9NaN
1011.0
1112.0
1213.0
dtype: float64
# Argument passed can also be a dictionary with separate values
data_replaced = combined_series.replace({-99: np.nan, -100: 0})# Same as: new_data.replace([-99, -100], [np.nan, 0])
data_replaced
01.0
12.0
2NaN
34.0
45.0
5NaN
67.0
78.0
8NaN
90.0
1011.0
1112.0
1213.0
dtype: float64
增加知识-地图功能
在某些情况下, 你可能希望基于某种逻辑对已经拥有的内容进行更多的了解。这是你可以从地图和功能组合中寻求帮助的时候。逻辑可能会变得更加复杂, 但是请在此示例的帮助下尝试理解。
假设你有一个数字数据框, 该数据框映射到其对应的英语计数。
data_number = pd.DataFrame({'english': ['zero', 'one', 'two', 'three', 'four', 'five'], 'digits': [0, 1, 2, 3, 4, 5]})
data_number
英语 | 数字 | |
---|---|---|
0 | zero | 0 |
1 | one | 1 |
2 | two | 2 |
3 | three | 3 |
4 | four | 4 |
5 | five | 5 |
english_to_multiple = {
'two': 'yes', 'four': 'yes'
}
然后, 当英语列是2的倍数时, 可以调用map函数添加该列。其他非整数列将填充什么?让我们找出…
data_number['multiple'] = data_number['english'].map(english_to_multiple)
data_number
英语 | 数字 | 多 | |
---|---|---|---|
0 | zero | 0 | NaN |
1 | one | 1 | NaN |
2 | two | 2 | yes |
3 | three | 3 | NaN |
4 | four | 4 | yes |
5 | five | 5 | NaN |
离散化-剪切功能
有时, 你可能希望基于某种逻辑进行分类, 然后将所有数据放入离散的存储桶或存储箱中以进行分析。你可以为此使用cut()函数。例如, 让我们首先创建一个数据集, 其中包含30个1至100之间的随机数。
import randomdata = http://www.srcmini.com/random.sample(range(1, 101), 30)
# data
[45, 39, 25, 83, 27, 6, 73, 43, 36, 93, 97, 17, 15, 99, 37, 5, 31, 22, 65, 30, 3, 26, 91, 12, 52, 76, 63, 84, 59, 53]
假设我们要按照我们定义自己的存储桶进行分类:数字1-25, 然后25-35, 40-60, 然后60-80, 然后是其余部分。所以我们定义一个桶…
然后, 我们将使用cut函数。
# Defining the starting value for each bucket
bucket = [1, 25, 35, 60, 80, 100]cut_data = http://www.srcmini.com/pd.cut(data, bucket)
cut_data
[(35, 60], (35, 60], (1, 25], (80, 100], (25, 35], ..., (60, 80], (60, 80], (80, 100], (35, 60], (35, 60]]
Length: 30
Categories (5, interval[int64]): [(1, 25] <
(25, 35] <
(35, 60] <
(60, 80] <
(80, 100]]
cut()是一个非常有用的函数, 你可以使用它做更多的事情。强烈建议你查看Pandas文档以了解更多信息。
虚拟变量和一键编码
当你希望能够将一些分类数据转换为数值以便可以在数据分析模型中使用时, 本主题特别有用。这特别方便, 特别是在进行机器学习建模时(其中一键编码的概念非常著名)。使用更专业的词:” 一键编码” 是将分类值转换为一维数字矢量的过程。
使用pandas的一种方法是使用get_dummies()函数。如果数据框中的一列具有” n” 个不同的值, 则该函数将派生一个矩阵, 其中” n” 个列包含全1和0。让我们看一个例子, 以更好地理解这个概念。
# Creating a DataFrame consiting individual characters in the list
data = http://www.srcmini.com/pd.Series(list('abcdababcdabcd'))
data
0a
1b
2c
3d
4a
5b
6a
7b
8c
9d
10a
11b
12c
13d
dtype: object
假设现在你要有单独的向量来指示每个字符的外观, 以将其提供给函数。
像这样:对于’ a’ = [1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0]其中1处于存在’ a’ 的位置, 并且0表示不存在。使用get_dummies()函数将使任务更加容易。
pd.get_dummies(data)
一种 | b | C | d | |
---|---|---|---|---|
0 | 1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 0 |
2 | 0 | 0 | 1 | 0 |
3 | 0 | 0 | 0 | 1 |
4 | 1 | 0 | 0 | 0 |
5 | 0 | 1 | 0 | 0 |
6 | 1 | 0 | 0 | 0 |
7 | 0 | 1 | 0 | 0 |
8 | 0 | 0 | 1 | 0 |
9 | 0 | 0 | 0 | 1 |
10 | 1 | 0 | 0 | 0 |
11 | 0 | 1 | 0 | 0 |
12 | 0 | 0 | 1 | 0 |
13 | 0 | 0 | 0 | 1 |
现在怎么办? 好了, 你到了本教程的结尾, 并且你已经学习了一些基本工具来开始数据分析路径中的第一步。学习数据准备步骤的其他技能还包括学习如何检测和过滤数据集中的异常值, 以及数据集是否庞大-也许从随机抽样开始。但是这些本身又是广泛的话题, 很难一概而论。
现实中的用例通常可能更复杂, 并且可能需要其自己独特的解决方案, 但其想法是从小处着手并在此过程中进行学习, 并探索更多并用不同的数据集弄脏你的手!确保检查出srcmini的Python清洗数据课程, 以了解更多工具和技巧, 最后, 你将开始研究从Gapminder Foundation获得的真实, 混乱的数据集。开始吧!
推荐阅读
- GIT推拉(push和pull)
- JupyterLab中的SQL接口
- Matplotlib中的直方图
- Pandas移动平均线
- 将数据导入Pandas
- 揭开深度学习数学概念的神秘面纱
- 如何在Windows,Mac OS X和Ubuntu上安装R
- 怎样创建宽带连接,本文教您宽带连接怎样创建
- 本次设置由于这台计算机的局限而被取消,本文教您怎样处理本次设置由于这台