虽然之前东一榔头,西一棒槌地学过一些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(每一行)中的相应值。
这时候我们的列名是自己规定的,但是行名(index)只是一个默认生成的0,1,2,…的序列,如果我们想要自定义行名,该怎么做呢?
很简单,只要在创建dataframe时,传入一个Index对象就可以了。
data2 = {'name':['Mike', 'Rose'], 'age':[20,19]}
df2 = pd.DataFrame(data2, index = ['user1', 'user2'])
这时候我们就会得到一个行名和列名都是自定义的dataframe。
现在来说说Series,它实际上就是一个数据序列。在我们的dataframe中,每一列都可以看成是一个series。
创建它的方式和dataframe差不多,只是要注意我们是没有列名的,因为只有一列,所以我们只能规定一个统一的name作为这个series的名字。
data3 = [_ for _ in range(3)]
sr = pd.Series(data3, index = ['开始','过程','结束'], name = 'mySeries')
这样我们就得到一个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')
选择数据
使用.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() #返回每个独特值的出现次数
我们可以对数据进行整体操作,主要有三种方法:
- map()
review_points_mean = reviews.points.mean()
reviews.points.map(lambda p: p - review_points_mean)
- apply()
def remean_points(row):
row.points = row.points - review_points_mean
return row
reviews.apply(remean_points, axis='columns')
- 直接操作
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])
如果想恢复到之前的Index形式,可以使用reset_index()。
countries_reviewed.reset_index() #注意这里并不会直接修改原数据。
对数据进行排序
直接groupby()得到的数据是按照Index顺序排列的,如果想要按照自己的方式排列数据,可以使用sort_values()。
countries_reviewed.sort_values(by=['country', 'len'], ascending = False)
同样的,如果希望回到最初的排列方式,可以使用sort_index()。
countries_reviewed.sort_index()
数据类型与缺失值
我们可以使用dtype来查看指定栏的数据类型,也可以使用dtypes来查看所有列的数据类型。
reviews.price.dtype
reviews.dtypes
可以使用astype来改变数据类型。
reviews.points.astype('float64')
查找缺失值
可以使用pd.isnull()来查找缺失值。
reviews[pd.isnull(reviews.country)]
填充缺失值
使用.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。
谢谢阅读。