这些好用的pandas操作

2019-08-17  本文已影响0人  九日照林
# 导入模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import seaborn as sns
import logging
from tqdm import tqdm
import warnings 
warnings.filterwarnings('ignore')
%matplotlib inline
plt.rc('font',family='SimHei', size=13)
# os.chdir('')

pandas本身对字符串的操作

pandas文本字符串的列本身就可以调用str属性里面的方法,跟python文本字符串本身带有的方法是一致的

movie_lens=pd.read_table('tmdb-movies.csv', sep=',')
movie_lens.head(2)
movie_lens['genres'].str.contains('Action').head(3)
0     True
1     True
2    False
Name: genres, dtype: object
movie_lens['genres'].str.find('Action').head(3)
0    0.0
1    0.0
2   -1.0
Name: genres, dtype: float64
movie_lens['genres'].str.split('|', expand=True).head(3)

获得指定位置的字符串

movie_lens['original_title'].str.get(1).head(3)
0    u
1    a
2    n
Name: original_title, dtype: object

字符串重复三遍

df.head(3)
df.key.str.repeat(3)
0     aaa
1     bbb
2     ccc
3     aaa
4     bbb
5     ccc
6     aaa
7     bbb
8     ccc
9     aaa
10    bbb
11    ccc
Name: key, dtype: object

find, findall, extract等可以结合正则表达式去用

df.key.str.title().head(3)
0    A
1    B
2    C
Name: key, dtype: object

pandas对时间格式的文本的转化

movie_lens.columns
Index(['id', 'imdb_id', 'popularity', 'budget', 'revenue', 'original_title',
       'cast', 'homepage', 'director', 'tagline', 'keywords', 'overview',
       'runtime', 'genres', 'production_companies', 'release_date',
       'vote_count', 'vote_average', 'release_year', 'budget_adj',
       'revenue_adj'],
      dtype='object')
movie_lens.release_date.head(3)
0     6/9/15
1    5/13/15
2    3/18/15
Name: release_date, dtype: object

python中时间日期格式化符号:

format meaning
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

我们可以使用pandas.to_datetime对日期列进行对应格式的转换,只需要传入一个对应的参数format附上对应的格式即可,如对电影数据集的release_date进行格式化

pd.to_datetime(movie_lens.release_date, format='%m/%d/%y').head(10)
0   2015-06-09
1   2015-05-13
2   2015-03-18
3   2015-12-15
4   2015-04-01
5   2015-12-25
6   2015-06-23
7   2015-09-30
8   2015-06-17
9   2015-06-09
Name: release_date, dtype: datetime64[ns]

pandas对分组后的高阶操作

我们先加载一个df

df = pd.DataFrame({'key': ['a', 'b', 'c'] * 4,
                   'value': np.arange(12.)})
df
key value
0 a 0.0
1 b 1.0
2 c 2.0
3 a 3.0
4 b 4.0
5 c 5.0
6 a 6.0
7 b 7.0
8 c 8.0
9 a 9.0
10 b 10.0
11 c 11.0
df['value_1']=np.random.randint(low=0, high=50,size=len(df))
df
key value value_1
0 a 0.0 44
1 b 1.0 4
2 c 2.0 12
3 a 3.0 15
4 b 4.0 29
5 c 5.0 7
6 a 6.0 20
7 b 7.0 10
8 c 8.0 38
9 a 9.0 6
10 b 10.0 40
11 c 11.0 0
g=df.groupby('key')

很多人不知道的是,pandas聚合后的对象其实是一个键值对的对象

# 我们试一下
for i, v in g:
    print(i, v)
a   key  value  value_1
0   a    0.0       44
3   a    3.0       15
6   a    6.0       20
9   a    9.0        6
b    key  value  value_1
1    b    1.0        4
4    b    4.0       29
7    b    7.0       10
10   b   10.0       40
c    key  value  value_1
2    c    2.0       12
5    c    5.0        7
8    c    8.0       38
11   c   11.0        0

三种聚合写法

pandas具有三种聚合写法。

  1. 一种是聚合后直接用某个函数比如mean()max()等聚合函数进行聚合
  2. 一种是聚合后用apply方法来传入一个自定义函数来获得相应的聚合结果
  3. 还有就是用agg(dict)的方法,agg里面传入一个字典,其中key是操作的列名,value是对应的聚合函数,既可以是通用的方法的字符串,比如'mean',也可以是自定义的函数对象,比如np.mean()或者是lambda x:x.mean(),好处是不同列可以一次过传入不同的函数进行不同的操作

我们试一下用以上三种方法分别对dataframe df进行操作

g['value'].mean()
key
a    4.5
b    5.5
c    6.5
Name: value, dtype: float64
g.agg({'value':np.mean, 'value_1':np.max})
g.agg({'value':'mean', 'value_1':'max'})
g.agg({'value':lambda x:np.power(x.mean(),2), 'value_1':'max'})
city=['washington', 'new york', 'boston']
df['city']=np.random.choice(city, size=len(df))
df.head()

案例一

按照key进行分组,统计组内去重后city列计数的结果,同时计算出value_1列的平均值

g=df.groupby('key')

g.agg({'city':lambda x:x.nunique(), 'value_1':'mean'})

可以对比下去重前后的差别

g.agg({'city':lambda x:x.count(), 'value_1':'mean'})
key city value_1
a 4 21.25
b 4 20.75
c 4 14.25

聚合后进行apply方法

g.apply(lambda df:df.sort_values(by='value_1',ascending=False))
key value value_1 city
('a', 0) a 0 44 washington
('a', 6) a 6 20 new york
('a', 3) a 3 15 boston
('a', 9) a 9 6 new york
('b', 10) b 10 40 boston
('b', 4) b 4 29 boston
('b', 7) b 7 10 boston
('b', 1) b 1 4 new york
('c', 8) c 8 38 boston
('c', 2) c 2 12 boston
('c', 5) c 5 7 new york
('c', 11) c 11 0 washington

组内聚合后进行广播

很多时候我们想对一组内的值进行聚合操作后再广播到相应的大小,这个时候可以用transform或者apply方法

g['value'].transform(lambda x:(x-x.mean())/x.std())
0    -1.161895
1    -1.161895
2    -1.161895
3    -0.387298
4    -0.387298
5    -0.387298
6     0.387298
7     0.387298
8     0.387298
9     1.161895
10    1.161895
11    1.161895
Name: value, dtype: float64
g['value'].transform('mean')
0     4.5
1     5.5
2     6.5
3     4.5
4     5.5
5     6.5
6     4.5
7     5.5
8     6.5
9     4.5
10    5.5
11    6.5
Name: value, dtype: float64
g['value'].apply(lambda x:(x-x.mean())/x.std())
0    -1.161895
1    -1.161895
2    -1.161895
3    -0.387298
4    -0.387298
5    -0.387298
6     0.387298
7     0.387298
8     0.387298
9     1.161895
10    1.161895
11    1.161895
Name: value, dtype: float64

用pivot_table

用pivot_table可以实现聚合相同的功能

df.head(3)
key value value_1 city
0 a 0 44 washington
1 b 1 4 new york
2 c 2 12 boston
pd.pivot_table(df, values='value_1', index='city', aggfunc='mean', fill_value=1)
city value_1
boston 24
new york 9.25
washington 22

类似于这样,index就是要group的列,value_1相当于是要用来计算的列,aggfunc就是使用的聚合函数,fill_value就是如果对应位置为空要填充的值

对应替换操作

我们在pandas的实际数据分析中,需要按照对应值去填充空值或者是替换值,我们可以用到map的技巧,也就是传入一个字典去对应填充或者替换

比如说,我们在这里按照
washington ----> 1
new york ----> 2
boston----> 3

city_dict={ 'washington':1, 'new york':2, 'boston':3 } 
df['city'].map(city_dict)
0     1
1     2
2     3
3     3
4     3
5     2
6     2
7     3
8     3
9     2
10    3
11    1
Name: city, dtype: int64

可以看到传入一个字典到map当中以后,相应的值就会被替换成字典里面对应的键的值

pandas本身的mapfilter也是相当好用的函数

a=list(range(5))
# map函数
print(list(map(lambda x:x**2,a )))
[0, 1, 4, 9, 16]
# 筛选出是偶数的元素
print(list(filter(lambda x:x%2==0,a )))
[0, 2, 4]

其他超级好用的模块

pandas_profiling

pandas_profiling这个模块用来前期的探索性分析是最好不过了,我们常用的会用head, info, describe等方法来实现对某个数据集的概览,而pandas_profiling则一步到位,直接实现了我们的所有幻想,并且生成的report还支持to_file方法直接导出为html文件,实在是省时省力,用来给老板汇报十分专业

import pandas_profiling as pp
pp.ProfileReport(movie_lens)
report=pp.ProfileReport(movie_lens)
# 将生成的侧写报告导出为html文件
report.to_file('report.html')

scatter_matrix

from pandas.plotting import scatter_matrix
scatter_matrix(movie_lens,figsize=(18, 18))
plt.show()

scatter_matrix可以绘制出多个变量的组合后的关系,从中我们看出一些比较明显的相关关系,进而去进一步探究它们的相关关系,比如上图的revenuebudget就存在明显的相关关系

一些相关的参数:

1。frame,pandas dataframe对象
2。alpha, 图像透明度,一般取(0,1]
3。figsize,以英寸为单位的图像大小,一般以元组 (width, height) 形式设置
4。ax,可选一般为none
5。diagonal,必须且只能在{‘hist’, ‘kde’}中选择1个,’hist’表示直方图(Histogram plot),’kde’表示核密度估计(Kernel Density Estimation);该参数是scatter_matrix函数的关键参数
6。marker。Matplotlib可用的标记类型,如’.’,’,’,’o’等
7。density_kwds。(other plotting keyword arguments,可选),与kde相关的字典参数
8。hist_kwds。与hist相关的字典参数
9。range_padding。(float, 可选),图像在x轴、y轴原点附近的留白(padding),该值越大,留白距离越大,图像远离坐标原点
10。kwds。与scatter_matrix函数本身相关的字典参数
11。c。颜色

sns.countplot

sns.countplot可以迅速对一列中的元素进行计数并且绘图,节省了pandas中的统计后再绘图的两步走,节省了功夫

sns.countplot(df.city)
<matplotlib.axes._subplots.AxesSubplot at 0x1a23e534e0>

目前先写这么多了,接下来在工作中如果遇到新的问题和好的解决方法会继续分享

上一篇下一篇

猜你喜欢

热点阅读