【置顶】Pandas Learning Notes

本文是对公开课Data analysis in Python with pandas (by Data School) 的总结整理

对应的ipython notebook内附于各节末尾

公开课系列视频: here

This note is recorded the public class of Data analysis in Python with pandas by Data School.

The series video is linked here

1. Introduction of Pandas

介绍pandas,不赘述

2. How do I read a tabular data file in to pandas?

如何用pandas读取表格数据

  • read_table:默认以“ ”(tab)为分割

  • read_csv : 默认以‘,’ 为分割

  • 几种参数: sep, header, names

    ipython

3. How do I select a pandas Series from a DataFrame?

如何从dataframe中选取一列/一行数据

  • 点选: column name
  • 方括号选择: 传入index或column name
  • 创建新column:用方括号

ipython

4. Why do some pandas commands end with parentheses, and other commands dont’?

有些dataframe的method要加括号,有些不用加括号:

  • 表示属性:不用加括号,如:shape, columns, index
  • 表示方法:加括号, 如:describe()

ipython

5. How do I rename columns in a pandas DataFrame?

如何重命名列名

  • 传入字典:rename({})
  • 传入列表: .columns =[]
  • 用str.handler: .columns.str.replace(' ','_')

ipython

6. How do I remove columns from a pandas DataFrame?

如何删除一列

  • 通过列名: drop(col_name,axis=1,inplace=True)
  • 通过列名列表: drop([col_name1,col_name2],axis=1,inplace=True)

如何删除一行

  • 通过改变axis=0

ipython

7. How do I sort a pandas DataFrame or Series?

如何对Series进行排序

  • 选中一列
  • sort_values()
  • returns a series
  • 默认升序,可调: ascending=False

如何对dataframe进行排序

  • 用单列排序:df.sort_values(col_name)
  • 用多列排序:df.sort_values([col_name1,col_name2,...])

ipython

8. How do I filter rows of a pandas DataFrame by column value?

筛选行

df[row condition]

df[df.col_name > 200]

筛选行和列

df.loc[row condition, col condition]

ipython

9. How do I apply multiple filter criteria to a pandas DataFrame?

如何实现多选

  • () & ()
  • () | ()
  • df.col_name.isin([])

ipython

10. How do I use the “axis” parameter in pandas?

在pandas的method中,常常要指定axis,轴。axis默认为0。

  • axis = 0: 移动方向为从上到下,即以行为方向延展
  • axis = 1: 移动方向为从左到右,即以列为方向延展
  • axis = 0 也可以说是 axis = 'index'
  • axis = 1 也可以说是 axis = 'columns'

ipython

11. How do I use string methods in pandas?

如何在pandas中用str的方法?(其他类型的方法也类似)

df.col_name.str.upper()

ipython

12. How do I change the data type of a pandas Series?

如何改变pandas某一列的数据类型?

查看数据类型

df.dtypes

转换类型

方法一 读完之后的转换

df.col_name = df.col_name.astype(float)

方法二 读文件时的转换

read_csv(...,dtype={'col_name','float'})

bonus

boolean类型可以直接通过astype(int)转换成0,1

ipython

13. When shoud I use a “groupby” in pandas?

groupby用于将一种类型的样本聚在一起

df.groupby(col_name)

返回一个dataframe,所以可以接着做操作:

df.groupby(col_name).col_name2.mean()

d

df.groupby(col_name).col_name2.agg(['count','mean','max','min']

bonus

画图:

1
2
%matplotlib inline
drinks.groupby('continent').mean().plot(kind='bar')

直接在想画的东西后面加.plot()即可画

ipython

14. How do I explore a pandas Series?

如何分析pandas中的列

按列描述

df.col_name.describe()

按列统计

df.col_name.value_counts()

比例化的按列统计

df.col_name.value_counts(normalize=True)

某列的值域

df.col_name.unique()

某列的取值个数

df.col_name.nunique()

两列交叉(一列作为行,一列作为列):

pd.crosstab(df.col_name1,df.col_name2)

其中,df.col_name1作为行,df.col_name2作为列

按列运算

df.col_name.mean()

bonus

按列绘图

1
2
3
4
5
%matplotlib inline

df.col_name.plot(kind='hist')

df.col_name.value_counts.plot(kind='bar')

ipython

15. How do I handle missing values in pandas?

如何处理缺失值?

缺失值在pandas中用numpy的NaN表示,在真实处理时,可以把这些缺失值替换掉,或者删掉对应的行或列

观察缺失值分布

df.isnull()

df.notnull()

按列统计缺失值个数: df.isnull().sum()

用缺失值来做筛选

df[df.col_name.isnull()]

缺失值的处理方法

方法1 drop any

如果每行中只要有一列缺失,则删除该行

df.dropna(how='any')

方法2 drop all

如果每行中每一列都缺失,则删除该行

df.dropna(how='all')

方法3 drop a subset

  • 如果每行中在指定的那几列中有任意一个缺失,则删除该行

df.dropna(subset=['col1,col2'], how='any')

  • 如果每行中在指定的那几列中都缺失,则删除该行

df.dropna(subset=['col1,col2'], how='all')

bonus

value_counts method中,默认不统计缺失值。可以通过传递参数来调整:

df.col_name.value_counts(dropna=False)

填充缺失值

df.col_name.fillna(value='some',inplace=True)

ipython

16. What do I need to know about the pandas index? (Part 1)

关于pandas的index(行号)

重置行号

df.set_index('col_name',inplace=True)

删除行号的名称

这个情况是出现在把某一列设置为index之后,如果这一列本来有列名,则该列名将会自动变成index的列名。但是列名通常是不需要的,所以可以删掉:

df.index.name=None

把行号再变回数据表中的一列

分成2步:

  • 给行号一个名称:df.index.name=col_name
  • 重置行号:df.reset_index(inplace=True)

bonus

describe() 返回一个dataframe结构,所以我们可以用它返回的内容做定位:

df.describe().loc['25%','col_name'] (返回某一列25%处的值)

ipython

17.How do I need to know about the pandas index? (Part 2)

用行号来筛选

df['row_name']

用行号来排序

df.sort_index()

用行号实现平行计算

如果有两个dataframe/或series,他们之间的结合可以用df.concat([dataframe1, dataframe2],axis=1) 来进行。则pd会自动根据相同的index放在所属的那一行,如果没有某行的index,则置为缺失值

ipython

18. How do I select multiple rows and columns from a pandas DataFrame?

如何选取多行、多列?

Loc

  • 通过行号、列号来进行选取,需分别指定行、列范围:

df.loc[0,:]

df.loc[[0,1,2],:]

  • 如果列号不指定,则默认为全部列:

df.loc[:100] (取第0-100行) 左闭右闭

  • 列名可以直接当做范围:

df.loc[:100,'one':'three'] (取列名为one的一列到three的三列) 左闭右闭

  • 通过条件选取:

df.loc[df.col_name > 10,:]

df.loc[df.col_name == 'some-name',:]

df.loc[df.col_name == 'some-row','some-col'] (推荐用法)

iloc

通过integer来选取行列

df.iloc[[0,1,2],:]

df.iloc[:2,:2]

注意:iloc是左闭右开的!

ix

不推荐使用,在以前的pandas版本中因为没有iloc和loc,所以才使用ix。现在的pandas版本中有了iloc和loc,所以就没必要使用ix了。不赘述

ipython

19. When should I use the “inplace” parameter in pandas?

inplace参数在很多pandas method中都有使用。

它的作用是将对pandas的处理原地执行,而不是仅仅产生一个view,是对原始的数据做真正的改变

  • df.drop('some-col',axis=1, inplace=True)
  • df.dropna(how='any',inplace=True)

注意:默认inplace=False

ipython

20. How do I make my pandas DataFrame smaller and faster? -use category

如何让dataframe又快又小?

  • 查看所占用内存:

df.info():查看到的是表面的内存大小(如字符串等,存放的仅是头指针,而不是真正的全部占用内存)

df.info(memory_usage='deep'): 查看真正的大小

df.info(memory_usage='deep').sum() :查看全部所占用内存的总和

  • 方法: 改变object类型为category类型

df['col_name']=df['col_name'].astype('category')

这样的话,就会将原来的字符串变量用一个字典存储,然后把对应的数字放在原地,这样就只要维护一个字典,和一些数字,而不用每一个都写对应的字符串

可以这样查看:

df.col_name.cat.codes

bonus

category可以用于排序时的指定顺序:

df['col_name'] = df.col_name.astype('category',categories=['A','B','C'],ordered=True)

这样的话,排序时就可以按照指定的[‘A’,’B’,’C’] 进行排列了:

df.sort_values('col_name')

还可以按照这个顺序进行大小比较:

df.loc[df.col_name > C,:]

ipython

21. How do I use pandas with scikit-learn to create Kaggle submissions?

打比赛的基本流程:

Step 1 加载数据

train = pd.read_csv('...')

Step 2 选择特征

features = ['col1','col2']

X = train.loc[:,features]

step 3 分离标签

Y = train['label']

Step 4 选择学习算法

  • 引入包
  • 新建分类器: cls = ...
  • fit: cls.fit(X,Y)

Step 5 预测

  • predict: result = cls.predict(test)

Step 6 输出到csv

pd.DataFrame({'uid':test.uid,'class':result}).set_index('uid').to_csv('submission.csv')

bonus

保存中间结果、数据等:

train.to_pickle('train.pkl')

train = pd.read_pickle('train.pkl')

ipython

22. sample

如果数据集太大了,我们想要采样处理的话,如何处理呢?

按个数采样

train = df.sample(n=3)

按比例采样

train = df.sample(frac=0.75,random_state=3)

而test set 则可以 :

test = df.loc[~df.index.isin(train.index),:]

ipython

23. How do I create dummy variables in pandas?

dummy实际上有点类似于one-hot,是将每一列中可能的取值都另起一列,然后用0表示不是该取值,用1表示是该取值

pd.get_dummies(df.col_name)

如col_name 有两个取值,则这样会生成两列由0,1组成的dataframe

还可以给这样的两列数组加上前缀:

pd.get_dummies(df.col_name, prefix='col_name')

bonus

可以一次性dummy好多列:

pd.get_dummies(df,columns=['col1','col2'])

由于是0,1取值,所以如果两种可能取值的列,只需要一个为1,就能知道另一个为0,所以只需要用一列即可,因此可以:

pd.get_dummies(df,columns=['col1','col2'],drop_first=True)

ipython

24. How do I work with dates and times in pandas?

如何处理时间信息

Step 1 转化成pandas 的时间类型

df['Time'] = pd.to_datetime(df.Time)

Step 2 使用

df.Time.dt.hour: 提取小时信息

df.Time.dt.weekday: 提取周几

df.Time.dt.dayofyear: 提取一年中的第几天

用作筛选条件

ts = pd.to_datetime('1/1/1999')

df.loc[df.Time >= ts,:]

做数学运算

df.Time.max()

bonus

1
2
3
%matplotlib inline
df['Year']= df.Time.dt.year
df.Year.value_counts().sort_index().plot()

按照年份画出每个年份有几条样本

ipython

25. How do I find and remove duplicate rows in pandas?

如何删掉重复记录

  • 计算某一列有几个重复数据:

df.col_name.duplicated().sum()

  • 计算在数据集中有几条重复记录:

df.duplicated().sum()

  • 查看最后一条重复记录:

df.loc[df.duplicated(keep='first'),:]

  • 查看第一条重复记录:

df.loc[df.duplicated(keep='last'),:]

  • 查看所有重复记录:

df.loc[df.duplicated(keep=False),:]

  • 删除最后一个重复数据:

df.drop_duplicates(keep='first')

  • 删除第一个重复数据:

df.drop_duplicates(keep='last')

  • 删掉所有重复数据:

df.drop_duplicates(keep=False)

bonus

可以指定希望不重复的子集:

df.drop_duplicates(subset=['col1','col2'],keep=False)

ipython

26. How do I avoid a Setting WithCopyWarning in pandas?

ipython

27. How do I change display options in pandas?

pandas的显示设置如何更改?

最大行数

pd.get_option('display.max_rows')

pd.set_option('display.max_rows',None) : 无限制

pd.reset_option('display.max_rows') :重置回默认值

最大列数

pd.get_option('display.max_columns')

pd.set_option('display.max_colwidth',100): 设置为100列

精度设置

pd.get_option('display.precision')

pd.set_option('display.precision',2):保留小数点后两位,不会改变原始数据,只改变显示

加分隔逗号

pd.set_option('display.float_format','{:,}'.format) : 1000 -> 1,000

bonus

  • 可以一次性查看所有显示设置:

pd.describe_option()

  • 或指定某个属性相关的设置:

pd.describe_option('row')

  • 重置所有设置:

pd.reset_option('all')

ipython

28. How do I create a pandas DataFrame from another object?

如何用其他object来创建dataframe?

字典

用字典创建,会自动将key作为columns,value作为对应的值

pd.DataFrame({'id':[100,101,102],'color':['red','blue','red']},columns = ['id','color'])

可以根据传入的columns参数来指定columns的顺序

还可以传入index

列表

列表默认没有columns和index, 可以通过指定来获得columns和index

np.array

直接传入

默认没有columns和index,可以通过指定来获得columns和index

bonus

将一个pd.Series 和dataframe相concat,则会自动根据index 进行结合

如果某个index 没有指定的值,则会置为缺失值

ipython

29. How do I apply a function to a pandas Series or DataFrame?

apply method可以用于对dataframe 或series做迭代操作,即对其中的每一个元素都做同样的操作

map

对Series

df.col_name.map({'val_1':'v1','val_2':'v2'})

apply

对Series

  • 传入built-in函数

df.col_name.apply(len)

  • 传入其他库的函数

df.col_name.apply(np.ceil): numpy的向上取整

传入自定义函数

1
2
3
4
def get_element(my_list, position):
return my_list[position]

df.col_name.str.split(',').apply(get_element,position=0)

或用lambda

df.col_name.str.split(',').apply(lambda x: x[0])

对DataFrame

df.apply(sum,axis=0): 从上到下,计算每一列的总和

或者直接df.sum()

df.apaply(np.argmax,axis=0) :得出每一列出现最多次的值

applymap

把一个类型映射成另一个类型,如int -> float:

df.applymap(float)