本文最后更新于:2022年3月26日 晚上
注册了kaggle之后就直接拿Titanic 练手,结果当然很不理想,只有0.76315分,然后看到有Courses ,所以打算把这些教程过一遍来了解这些基础概念,在这里做简单的记录,方便偶尔来回顾一下,有些地方被我省略了,有些地方直接对原文做了不严谨的翻译,也有些地方用自己的话表述了,,,
Pandas
Creating, Reading and Writing
Creating data
pandas 是最受欢迎的python数据分析包。pandas中有两个核心对象DataFrame 和Series 。
DataFrame 是一个表,由多个数组构成,这些数组常常作为表里面的列。使用pd.DataFrame()
来实例化一个DataFrame对象,数据参数使用的是python中的dict
,dict的key作为DataFrame的列名,dict的value是一个list,作为对应列的全部元素。
>>> pd.DataFrame({'Yes' : [50 , 21 ], 'No' : [131 , 2 ]}) Yes No0 50 131 1 21 2 >>> pd.DataFrame({'Bob' : ['I liked it.' , 'It was awful.' ], 'Sue' : ['Pretty good.' , 'Bland.' ]}) Bob Sue0 I liked it. Pretty good.1 It was awful. Bland.
行的下标(通常称为索引(index))默认和python的list一样,从0开始,也可以在构造时自定义
>>> pd.DataFrame({'Bob' : ['I liked it.' , 'It was awful.' ], 'Sue' : ['Pretty good.' , 'Bland.' ]}, index=['Product A' , 'Product B' ]) Bob Sue Product A I liked it. Pretty good. Product B It was awful. Bland.
Series 是一系列的数据,DataFrame是table,而Series是list,并且也可以设置index,但是没有列名,只可以设置一个name
>>> pd.Series([1 , 2 , 3 , 4 , 5 ])0 1 1 2 2 3 3 4 4 5 dtype: int64>>> pd.Series([30 , 35 , 40 ], index=['2015 Sales' , '2016 Sales' , '2017 Sales' ], name='Product A' )2015 Sales 30 2016 Sales 35 2017 Sales 40 Name: Product A, dtype: int64
可以将DataFrame视为粘在一起的Series。
Reading data files
wine_reviews = pd.read_csv("../input/wine-reviews/winemag-data-130k-v2.csv" ) wine_reviews.shape wine_reviews.head()
pd.read_csv()
的功能强大,可以指定30多个可选参数,比如可以设置csv文件的第0列作为索引:
wine_reviews = pd.read_csv("../input/wine-reviews/winemag-data-130k-v2.csv" , index_col=0 )
将DataFrame写入csv文件:
animals.to_csv("cows_and_goats.csv" )
Indexing, Selecting & Assigning
如果reviews这个DataFrame中包含列名"country",那么可以通过reviews.country
或reviews['country']
来访问这一列。
Indexing in pandas
pandas有自己的访问数据的方式:loc
和iloc
。
Index-based selection
可以用iloc
这样访问第一行的数据:
可以这样检索第一列的数据:
在python中:
代表全部,在字符串分割的时候,s[:]
即s[0:len(s)]
,在这里也可以这样使用,比如获取第0列,前3行的数据:
reviews.iloc[:3 , 0 ] reviews.iloc[[0 , 1 , 2 ], 0 ]
Label-based selection
loc
遵循以基于lable的选择,比如可以通过reviews.loc[0, 'country']
来访问’country’的首行位置的数据。
iloc把DataFrame看作一个二维矩阵,通过各种方式来获取对应位置的数据,loc更像把DataFrame看作Excel的表,可以通过lable来选择数据。
reviews.loc[:, ['taster_name' , 'taster_twitter_handle' , 'points' ]]
Choosing between loc
and iloc
0:10
在loc
中表示0 , 1 , . . . , 10 0,1,...,10 0 , 1 , . . . , 1 0 (闭区间),而在iloc
中表示0 , 1 , . . . , 9 0,1,...,9 0 , 1 , . . . , 9 (左闭右开)。
比如第3列的列名是"Apples",可以DataFrame.iloc[:, 2]
来访问这一列的数据,也可以使用DataFrame.loc['Apples']
,显然后者更直观。
Conditional selection
>>> reviews.country == 'Italy' 0 True 1 False ... 129969 False 129970 False Name: country, Length: 129971 , dtype: bool
可以通过运算符构造条件筛选出想要的数据:
reviews.loc[reviews.country == 'Italy' ] reviews.loc[(reviews.country == 'Italy' ) & (reviews.points >= 90 )] reviews.loc[(reviews.country == 'Italy' ) | (reviews.points >= 90 )]
isin
类似python的is in
,筛选country为’Italy’或’France’的数据可以:
reviews.loc[reviews.country.isin(['Italy' , 'France' ])]
isnull
和notnull
用来判断是否为NaN
: reviews.loc[reviews.price.notnull()]
Assigning data
DataFrame也支持更改表中的数值:
>>> reviews['critic' ] = 'everyone' >>> reviews['critic' ]0 everyone1 everyone ... 129969 everyone129970 everyone Name: critic, Length: 129971 , dtype: object >>> reviews['index_backwards' ] = range (len (reviews), 0 , -1 )>>> reviews['index_backwards' ]0 129971 1 129970 ... 129969 2 129970 1 Name: index_backwards, Length: 129971 , dtype: int64
Summary Functions and Maps
Summary functions
pandas提供了一些汇总函数,比如之前提到过的describe()
,DataFrame可以直接调用:reviews.points.describe()
。
describe()
对类型敏感,对于不同的数据类型,也会返回不同的结果。对于数字类型的数据,调用describe()
会显示mean
等信息,也可以直接使用reviews.points.mean()
获取。
reviews.taster_name.unique() reviews.taster_name.value_counts()
如果想要获取这些分数和平均值的差距,可以使用map()
,返回这一列Series,不会覆盖原来的值:
review_points_mean = reviews.points.mean() reviews.points.map (lambda p: p - review_points_mean)
如果想获取整个DataFrame,可以使用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进行操作,就像在python中直接用数字和list运算,显然在python里是不允许的,但是pandas会知道将Series的每一个值和这个数操作,而且速度比map
和apply
更快,但是map
和apply
更灵活,可以做更高级的事情。
计算"tropical"和"fruity"在description
中出现的次数:
n_trop = reviews.description.map (lambda desc: "tropical" in desc).sum () n_fruity = reviews.description.map (lambda desc: "fruity" in desc).sum () descriptor_counts = pd.Series([n_trop, n_fruity], index=['tropical' , 'fruity' ])
Grouping and Sorting
Groupwise analysis
分组可以把某一列值相同的数据合为一组,然后我们可以获取这些组的各种信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 >>> reviews.groupby('points' ).points.count() points80 397 81 692 ... 99 33 100 19 Name: points, Length: 21 , dtype: int64>>> reviews.groupby('points' ).price.min () points80 5.0 81 5.0 ... 99 44.0 100 80.0 Name: price, Length: 21 , dtype: float64>>> reviews.groupby('winery' ).apply(lambda df: df.title.iloc[0 ])>>> reviews.groupby(['country' , 'province' ]).apply(lambda df: df.loc[df.points.idxmax()])
Multi-indexes
groupby有时候会用到多索引MultiIndex
,可以用reset_index()
把它转换成常规的索引。如果想要获取多列值,需要使用agg([])
>>> countries_reviewed = reviews.groupby(['country' , 'province' ]).description.agg([len ])>>> mi = countries_reviewed.index>>> type (mi) pandas.core.indexes.multi.MultiIndex>>> countries_reviewed.reset_index()
Sorting
sort_values()
默认是升序排序,可以更改参数ascending=False
来使其降序排序,
countries_reviewed = countries_reviewed.reset_index() countries_reviewed.sort_values(by='len' ) countries_reviewed.sort_index() countries_reviewed.sort_values(by=['country' , 'len' ])
Data Types and Missing Values
Dtypes
DataFrame或Series中某一列的数据类型(data type)称为 Dtype 。
>>> reviews.price.dtype dtype('float64' )>>> reviews.dtypes country object description object ... variety object winery object Length: 13 , dtype: object
使用astype()
函数可以将一种类型的列转换为另一种类型:
>>> reviews.points.astype('float64' )0 87.0 1 87.0 ... 129969 90.0 129970 90.0 Name: points, Length: 129971 , dtype: float64
index也有自己的Dtype:reviews.index.dtype
(dtype(‘int64’))
Missing data
缺失值会自动被赋值NaN
,它的Dtype始终是’float64’。pandas也提供了一些函数来用NaN筛选数据,比如pd.isnull()
和pd.notnull()
:
reviews[pd.isnull(reviews.country)]
fillna()
可以直接用某些值 比如"Unknown"替换NaN
:
reviews.region_2.fillna("Unknown" )
replace()
函数可以把某列的"@kerinokeefe"替换成"@kerino":
reviews.taster_twitter_handle.replace("@kerinokeefe" , "@kerino" )
Renaming and Combining
Renaming
rename()
可以用来修改列名或索引名,下面这个例子是:
reviews.rename(columns={'points' : 'score' }) reviews.rename(index={0 : 'firstEntry' , 1 : 'secondEntry' })
行(rows)和列(columns)的名字也是可以更改的:
reviews.rename_axis("awines" , axis='rows' ).rename_axis("fields" , axis='columns' )
Combining
pandas有三种方法用来组合DataFrame(Series),concat()
、join()
和merge()
。
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])
就复杂性而言,最中间的组合器是join()
,join()
允许组合具有共同索引的不同DataFrame
对象。 例如,要合并恰好在同一天在加拿大和英国流行的视频,我们可以执行以下操作:
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
是分别给left和right这两个DataFrame的列名加后缀的,因为这两个DataFrame中含有相同的列名,所以加上列名来避免冲突,如果已经提前为这两个DataFrame重命名过,保证没有列名的冲突,就可以不用设置这两个参数。
Data Visualization
…