Pandas数据处理:清洗与处理

本文素材来源于towardsdatascience技术博客网站,经本人编辑首发于CSDN,仅供技术分享所用,不作商用。

原文地址:https://towardsdatascience.com/data-handling-using-pandas-cleaning-and-processing-3aa657dc9418

Mastering Pandas to Deal with ‘Dirty Data’

作者:Saptashwa
Pandas数据处理:清洗与处理_第1张图片
在做一些老的Kaggle项目练习时,我意识到在应用机器学习算法之前准备数据文件需要花费很多时间。这篇文章是之前一篇文章的后续,让初学者快速学习并掌握Pandas,以进阶到更高level的数据处理技术大神。让我们开始吧!

对于这篇文章,我使用IMDB电影数据集来涵盖最相关的数据清理和处理技术。我们可以先了解下这个数据集的有关信息,如下所示:

movies_df = pd.read_csv("movie_metadata.csv")
print "data-frame shape: ", movies_df.shape
>>> data-frame shape: (5043, 28)

所以,数据集有5043行,28列,我们可以检查列名:

print "column names: ", movies_df.columns.values
>>> column names:
['color' 'director_name' 'num_critic_for_reviews'
'duration'
 'director_facebook_likes' 'actor_3_facebook_likes'
'actor_2_name'
 'actor_1_facebook_likes' 'gross' 'genres'
'actor_1_name' 'movie_title'
 'num_voted_users' 'cast_total_facebook_likes'
'actor_3_name'
 'facenumber_in_poster' 'plot_keywords'
'movie_imdb_link'
 'num_user_for_reviews' 'language' 'country'
'content_rating' 'budget'
 'title_year' 'actor_2_facebook_likes' 'imdb_score'
'aspect_ratio'
 'movie_facebook_likes']

在我们应用一些机器学习算法进行预测之前,让我们说’imdb_score’,我们需要更多地调查数据集位,因为它不像Boston House Data-Set那样那么好处理。首先,我将讨论如何处理丢失的数据。

处理缺失数据:DataFrame.isna(),DataFrame.fillna()

我们可以使用pandas.DataFrame.isna()检测像object这样的数组的缺失值。这将返回一个布尔相同大小的对象,其中NA值(如None或numpy.NaN)将映射为True,其他所有值都映射为False。这与pandas.DataFrame.isnull()的功能完全相同 。

print“null values:\ n”,
print movies_df.isna()

以上命令返回以下输出
Pandas数据处理:清洗与处理_第2张图片
我们可以通过再增加一个.sum()命令来提取相关信息,而不是简单使用判断True/False输出整个data-frame的数据缺失情况。有了这个,我们可以找到每列的缺失值总数。

print movies_df.isna().sum()
>>>
color 19
director_name 104
num_critic_for_reviews 50
duration 15
director_facebook_likes 104
actor_3_facebook_likes 23
actor_2_name 13
actor_1_facebook_likes 7
gross 884
genres 0
actor_1_name 7
movie_title 0
num_voted_users 0
cast_total_facebook_likes 0
actor_3_name 23
facenumber_in_poster 13
plot_keywords 153
movie_imdb_link 0
num_user_for_reviews 21
language 12
country 5
content_rating 303
budget 492
title_year 108
actor_2_facebook_likes 13
imdb_score 0
aspect_ratio 329
movie_facebook_likes 0
dtype: int64

添加另一个.sum()将返回整个数据集中的空值数。

print "total null values: ",
movies_df.isna().sum().sum()
>> total null values: 2698

删除包含NA的行的最简单方法之一是删除不管是所有列都包含NA还是只有某一列包含NA的行。让我们从删除任何列中包含NA值的行开始。

clean_movies_df = movies_df.dropna(how='any')
print "new dataframe shape: ", clean_movies_df.shape
print "old dataframe shape: "

得到:

>>>
new dataframe shape: (3756, 28)
old dataframe shape: (5043, 28)

可以看到,在删除任何列中包含NA值的行会导致将近1300行减少。这对于具有较少行数的数据集影响非常大,因为其中丢弃具有任何缺失值的所有行可能使我们失去必要的信息。在这种情况下,我们可以使用pandas.DataFrame.fillna(),利用指定的方法填充NA/NaN值。例如,最简单的一种方法是用一些固定值填充所有NA/NaN,例如0。

movies_df.fillna(value=0, inplace = True)

当然,我们可以选择一些特定的列,然后使用DataFrame.fillna()进行固定值填充,而不是所有列的缺失值都用0填充。

movies_df[['gross', 'budget']] = movies_df[['gross',
'budget']].fillna(value=0)

对于“object” 格式的列,例如“language”列,我们可以使用“no info”之类的单词来填充缺少的条目。

movies_df['language'].fillna("no info", inplace=True)

另一个填充缺失值的方法是ffill方法,它能够将上一个有效观察值赋给下一个。类似的是bfill方法,它将使用下一个观察值来填补空缺值。

movies_df['language'].fillna(method='ffill',inplace=True)

另外,还有一种有效的方法是使用列的平均值来填充缺失值,如下所示:

movies_df['budget'].fillna(movies_df[budget].mean(),inplace=True)

有关如何使用Pandas处理缺失值的更多详细信息,您可以查看Pandas用户指南文档关于缺失数据处理的相关章节。

DataFrame中的重复数据处理:DataFrame.duplicated()

除了数据缺失外, DataFrame中还可能存在重复的行。要查找数据集是否包含重复行,我们可以对所有列或某些选定列使用Pandas DataFrame.duplicated()。pandas.Dataframe.duplicated()返回表示重复行的布尔系列值。让我们首先找到这部电影数据集中有多少重复行。

duplicate_rows_df = movies_df[movies_df.duplicated()]
print "number of duplicate rows: ", duplicate_rows_df.shape

>>>
number of duplicate rows: (45, 28)

可以看到,在每列中都有45行存在重复元素的数据。当然,我们也可以对重复列进行查询:

duplicated_rows_df_imdb_link=movies_df[movies_df.duplicated(['movie_imdb_link'])]
print duplicate_rows_df_imdb_link.shape

>>>
(124, 28)

因此,movie_imdb_link列中有124个案例的imdb链接完全相同。另一种检查是否有相同元素的方法是使用pandas.Series.unique()。让我们来看看:

print len(movies_df.movie_imdb_link.unique())
>>>
4919

也就是说,无重复imdb链接的总行数为4919。如果您注意到之前重复链接为124,那么加上它们,则会得到(4919 + 124 = 5043)的总行数。为了更好的分析数据,我们很有必要选择无重复的行进行处理。因此,至少我们可以在所有列中删除具有相同值的行。我们可以简单地使用pandas.DataFrame.drop_duplicates()进行如下处理:

print "shape of dataframe after dropping duplicates",
movies_df.drop_duplicates().shape

>>>
shape of dataframe after dropping duplicates (4998,28)

数据分箱:pandas.cut()

另一种非常重要的数据处理技术是数据分桶或者分箱(data bucketing 或data binning)。我们将在这里举一个对IMDb-score使用pandas.cut()方法进行分箱的示例。基于[0.,4.,7.,10.]四个门槛得分值,我想将电影按照其实际得分放在不同的桶中[‘shyyyte’, ‘moderate’, ‘good’](实际意义为:['烂电影,‘还行的电影’,‘好看的电影’])。你可以理解得分在0-4之间的电影将被放入’shyyyte’的桶中,依次类推。我们可以使用以下代码行完成此操作:

op_labels = ['shyttte', 'moderate', 'good']
category = [0.,4.,7.,10.]
movies_df['imdb_labels'] =pd.cut(movies_df['imdb_score'], labels=op_labels, bins=category, include_lowest=False)

这里创建了一个包含标签’imdb_labels’的新列,让我们来看看它 。

print movies_df[['movie_title', 'imdb_score','imdb_labels']][209:220]

>>>
 movie_title imdb_score imdb_labels
209 Rio 2 6.4 moderate
210 X-Men 2 7.5 good
211 Fast Five 7.3 good
212 Sherlock Holmes:.. 7.5 good
213 Clash of the... 5.8 moderate
214 Total Recall 7.5 good
215 The 13th Warrior 6.6 moderate
216 The Bourne Legacy 6.7 moderate
217 Batman & Robin 3.7 shyttte
218 How the Grinch.. 6.0 moderate
219 The Day After T.. 6.4 moderate

如果要更详细的学习 pandas.cut() 方法,请查看相对应文档。

数据集中的异常值检测:

在探索性数据分析(EDA)的大部分时间,异常值(也称为离群值,Outliers)检测是一个重要的部分,因为一些特别的features中的异常值可能会扭曲真实情况,因此我们在数据分析时,不能将异常值和其他值一样同等对待处理。具体来说,当我们想要应用机器学习算法进行预测时,异常值可能会造成严重破坏。不过话说回来,异常值有时也可以帮助我们进行异常检测。那么,我们来看看如何使用Pandas来检测这个特定data-frame中的异常值。

Seaborn Box Plot:

箱形图是一种基于中位数,四分位数和异常值可视化数据分布的标准方法。可能你已经知道这些quantities到底是什么,但我仍然在下图中做了简短的回顾。
Pandas数据处理:清洗与处理_第3张图片
我们可以使用python的数据可视化库Seaborn来绘制这样的箱形图。让我们使用box plot来绘制电影海报中的演员数量分布。

sns.boxplot(x=movies_df['facenumber_in_poster'],
color='lime')
plt.xlabel('No. of Actors Featured in Poster',
fontsize=14)
plt.show()

运行上面的代码后,结果如下图所示:

Pandas数据处理:清洗与处理_第4张图片
让我们看看哪部电影的电影海报中有最多的演员(面孔)数量。

print movies_df[['movie_title','facenumber_in_poster']].iloc[movies_df['facenumber_in
_poster'].idxmax()]

>>>
movie_title 	500 Days of Summer
facenumber_in_poster 	43

因此,电影“500 Days of Summer”中有最多的面孔(43)。我们再利用pandas.DataFrame.describe()方法,看看此列’facenumber_in_poster’的基本统计详细信息。

print movies_df['facenumber_in_poster'].describe()

>>>
count 5030.000000
mean 1.371173
std 2.013576
min 0.000000
25% 0.000000
50% 1.000000
75% 2.000000
max 43.000000

有了这些,你就能更好的弄清楚刚才Box Plot图中的数据含义了。

Z Score和异常值

Pandas数据处理:清洗与处理_第5张图片
Z score是一个无量纲的数,表示数据点与平均值的标准偏差。Z score简单可以定义为 :Z =(X-μ)/σ,其中μ是总体均值,σ是标准偏差,X是总体中的一个元素。

为了绘制上图,我使用了正态分布numpy.random.normal()。在正态分布中,几乎所有的值 - 大约99.7%,落在平均值的3σ偏差内(对于此处的图,μ= 0)。我们使用Z score拒绝异常值的方法是考虑Z score 3个单位内的数据点。这可以使用“non object”类型数据对所有列进行scipy.stats,如下所示。

1.检查data-frame中所有列的数据类型(DataFrame.dtypes)

print "data types: \n", movies_df.dtypes
>>>
data types:
color object
director_name object
num_critic_for_reviews float64
duration float64
director_facebook_likes float64
actor_3_facebook_likes float64
actor_2_name object
actor_1_facebook_likes float64
gross float64
genres object
actor_1_name object
movie_title object
num_voted_users int64
cast_total_facebook_likes int64
actor_3_name object
facenumber_in_poster float64
plot_keywords object
movie_imdb_link object
num_user_for_reviews float64
language object
country object
content_rating object
budget float64
title_year float64
actor_2_facebook_likes float64
imdb_score float64
aspect_ratio float64
movie_facebook_likes int64

2.使用DataFrame.select_dtypes创建一个列中不含“object”类型的新data-frame

print "shape before :", movies_df.shape
movies_df_num = movies_df.select_dtypes(exclude=['object'])
print "shape after excluding object columns: ", movies_df_num.shape

>>>
shape before : (3756, 28)
shape after excluding object columns: (3756, 16)

3.从每列中选择位于Z score的3个单位内的元素

movies_df_Zscore =movies_df_num[(np.abs(stats.zscore(movies_df_num))<3).all(axis=1)]
print "shape after rejecting outliers: ",movies_df_Zscore.shape

>>>
shape after rejecting outliers: (3113, 16)

Pandas数据处理:清洗与处理_第6张图片
我们可以通过再次绘制’facenumber_in_poster’的box plot图来检查上述步骤的效果。在这里,我们可以明显看到去除异常值后的figure4与figure2的差异(figure2中的box plot图,我们考虑的是’facenumber_in_poster’列中的所有元素)。


以上这些是可用于数据分析和应用机器学习算法进行预测前的数据预处理的一些方法。对数据集进行有效的预处理,能够让后续的数据分析更加全面。我希望这篇文章能帮助您。更多关于机器学习的代码可在我的Github(suvoooo/Machine_Learning)上找到。

你可能感兴趣的:(项目学习)