0
点赞
收藏
分享

微信扫一扫

【数据处理】在kaggle学pandas

影子喵喵喵 2022-04-29 阅读 67

虽然之前东一榔头,西一棒槌地学过一些pandas和numpy,但学得实在是很没有章法,用起来也很不顺手,所以决定跟着kaggle的课程重新过一遍。本次先主要学习pandas。

创建和读写

在进行数据处理前,首先我们要有数据。

创建读写对象

在pandas中主要有两种数据类型,一种叫series,一种叫dataframe。我们先来看dataframe。
Dataframe实际上就是一张用来填数据的表,在创建的时候一般使用字典结构。

import pandas as pd

data = {'name':['Mike', 'Rose'], 'age':[20,19]}
df = pd.DataFrame(data)

可以看到dataframe中可以存储任意类型的数据,可以是字符串也可以是整数。
创建后字典中的key值会是表格中的列名,而value值则会对应每一个entry(每一行)中的相应值。
一个简单的dataframe
这时候我们的列名是自己规定的,但是行名(index)只是一个默认生成的0,1,2,…的序列,如果我们想要自定义行名,该怎么做呢?
很简单,只要在创建dataframe时,传入一个Index对象就可以了。

data2 = {'name':['Mike', 'Rose'], 'age':[20,19]}
df2 = pd.DataFrame(data2, index = ['user1', 'user2'])

这时候我们就会得到一个行名和列名都是自定义的dataframe。
新的dataframe
现在来说说Series,它实际上就是一个数据序列。在我们的dataframe中,每一列都可以看成是一个series。
创建它的方式和dataframe差不多,只是要注意我们是没有列名的,因为只有一列,所以我们只能规定一个统一的name作为这个series的名字。

data3 = [_ for _ in range(3)]
sr = pd.Series(data3, index = ['开始','过程','结束'], name = 'mySeries')

这样我们就得到一个series对象啦!
一个series

直接读取文件

很多时候我们需要直接读现成的数据文件,只需一行代码即可搞定。
以读取csv为例。

data = pd.read_csv('存储数据文件的地址', index_col = 0)

这里设置index_col = 0的目的是直接使用文件中规定的Index。

将DataFrame导出保存

一行代码即可实现,依然以csv为例。

data.to_csv('要保存到的地址')

选择和赋值

基于index的选择(iloc)

.iloc接受的是所要选取元素的存储位置。

reviews.iloc[1:3,0]

返回第二行到第三行,第一列的数据。

基于label的选择(loc)

.loc接受的是所要选取元素的名称。

reviews.loc[:, ['taster_name', 'taster_twitter_handle', 'points']]

注意

iloc不包含结尾项,loc包含结尾项。
比如data.iloc[3:7],不包含7,而data.loc[3:7]则包含7。

重设index

有时候我们希望用数据中的某一列作为新的Index:

reviews.set_index('title')

set_index

选择数据

使用.loc和逻辑组合可以很方便地选出我们想要的数据。

reviews.loc[(reviews.country == 'Italy') & (reviews.points >= 90)]

比如这里我们选取产自意大利且评分大于等于90的产品。

reviews.loc[reviews.price.notnull()]

选取价格不为空值的产品。

赋值

可以直接指定值。

reviews['critic'] = 'everyone'
reviews['critic']

这样会生成一个和reviews一样长,所有项都为everyone的series。

我们还可以找指定类型的数据:

revies.loc[reviews.country.isin(['Australia', 'Italy'])]

这样会选取产地为澳大利亚或意大利的产品。

批量数据处理

pandas的一大好处就是可以很方便地对数据进行批量操作。

reviews.points.describe()

describe() 可以帮助我们快速地查看数据的总体情况,注意数据类型不同时返回的值也不同。

reviews.points.mean() #返回平均值
reviews.country.unique() #返回所有独特值(不重复的元素)
reviews.country.value_counts() #返回每个独特值的出现次数

我们可以对数据进行整体操作,主要有三种方法:

  1. map()
review_points_mean = reviews.points.mean()
reviews.points.map(lambda p: p - review_points_mean)
  1. apply()
def remean_points(row):
    row.points = row.points - review_points_mean
    return row

reviews.apply(remean_points, axis='columns')
  1. 直接操作
review_points_mean = reviews.points.mean()
reviews.points - review_points_mean

注意

这些操作都不会改变原始数据,而是返回一个新的Series/DataFrame。

批量操作

groupby() 是pandas中最常使用的方法之一,这个函数可以很方便地根据我们的要求来聚合数据。

reviews.groupby(['country', 'province']).apply(lambda df: df.loc[df.points.idxmax()])

我们还可以使用agg()来一次对数据进行多种操作。

reviews.groupby(['country']).price.agg([len, min, max])

在使用groupby时,如果传入多个标签值,我们会得到multi-index的dataframe。

countries_reviewed = reviews.groupby(['country', 'province']).description.agg([len])

multi-index
如果想恢复到之前的Index形式,可以使用reset_index()。

countries_reviewed.reset_index() #注意这里并不会直接修改原数据。

reset_index()

对数据进行排序

直接groupby()得到的数据是按照Index顺序排列的,如果想要按照自己的方式排列数据,可以使用sort_values()。

countries_reviewed.sort_values(by=['country', 'len'], ascending = False)

sort_values()

同样的,如果希望回到最初的排列方式,可以使用sort_index()。

countries_reviewed.sort_index()

数据类型与缺失值

我们可以使用dtype来查看指定栏的数据类型,也可以使用dtypes来查看所有列的数据类型。

reviews.price.dtype
reviews.dtypes

可以使用astype来改变数据类型。

reviews.points.astype('float64')

astype

查找缺失值

可以使用pd.isnull()来查找缺失值。

reviews[pd.isnull(reviews.country)]

isnull

填充缺失值

使用.fillna(‘填充值’)来填充缺失值。

reviews.region_2.fillna('Unknown')

例如这里是使用字符串Unknow来填充缺失值。

改变值

使用.replace(原始值,更改值)来进行值的替换操作。

reviews.taster_twitter_handle.replace('@kerinokeefe','@kerino')

改变列名/行名

使用rename()

reviews.rename(columns = {'points':'score'})

同时可以使用rename_axis()来指定行和列的名称

reviews.rename_axis('wines', axis = 'rows').rename_axis('fields', axis = 'columns')

组合数据(concat和join)

concat():组合相同columns的数据
join():组合相同Index的数据

canadian_youtube = pd.read_csv("../input/youtube-new/CAvideos.csv")
british_youtube = pd.read_csv("../input/youtube-new/GBvideos.csv")

pd.concat([canadian_youtube, british_youtube])
left = canadian_youtube.set_index(['title', 'trending_date'])
right = british_youtube.set_index(['title', 'trending_date'])

left.join(right, lsuffix='_CAN', rsuffix='_UK')

注意如果两个表格的列名不一样,可以不用传入lsuffix和rsuffix。

谢谢阅读。

举报

相关推荐

0 条评论