导图社区 Pandas入门一篇就够了
学习 pandas,有这一篇就够了。还可以当做 cookbook 使用。心血之作,分享出来,让更多人受益。
编辑于2021-08-31 11:20:41Pandas教程
一、 基本介绍
Pandas 是 Python 语言的一个扩展程序库,用于数据分析。
Pandas 是一个开放源码、BSD 许可的库,提供高性能、易于使用的数据结构和数据分析工具。
Pandas 名字衍生自术语 "panel data"(面板数据)和 "Python data analysis"(Python 数据分析)。
Pandas 一个强大的分析结构化数据的工具集,基础是 Numpy(提供高性能的矩阵运算)。
Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。
Pandas 可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。
Pandas 广泛应用在学术、金融、统计学等各个数据分析领域。
pandas引入约定:
from pandas import Series , DataFrame
import pandas as pd
官方API文档:https://pandas.pydata.org/pandas-docs/stable/reference/index.html
二、 安装
安装Anaconda。见Python思维导图。
三、 Series
Series 是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
Series构造方法:
pandas.Series( data, index, dtype, name, copy)
参数说明:
data:一组数据(ndarray 类型)。
index:数据索引标签,如果不指定,默认从 0 开始。
dtype:数据类型,默认会自己判断。
name:设置名称。
copy:拷贝数据,默认为 False。
Series构造实例:
默认索引
data = [1, 2, 3] ser1 = pd.Series(data)
data = np.arange(3) ser1 = pd.Series(data)
指定索引
data = ["Google", "Runoob", "Wiki"] ser2 = pd.Series(data, index = ['x', 'y', 'z'])
以字典构建Series
data = {1: "Google", 2: "Runoob", 3: "Wiki"} ser3 = pd.Series(data)
字典的 key 变成了索引值。
data = {1: "Google", 2: "Runoob", 3: "Wiki"} ser3 = pd.Series(data, index = [1, 2])
指定字典的部分索引。
四、 DataFrame
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
DataFrame 构造方法如下:
pandas.DataFrame( data, index, columns, dtype, copy)
参数说明:
data:一组数据(ndarray、series, map, lists, dict 等类型)。
index:索引值,或者可以称为行标签。
columns:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。
dtype:数据类型。
copy:拷贝数据,默认为 False
DataFrame构造实例:
二维数组
data = [['Google',10], ['Runoob',12], ['Wiki',13]] df = pd.DataFrame(data, columns=['Site','Age'])
data = [['Google',10],['Runoob'],['Wiki',13]] df = pd.DataFrame(data, columns=['Site','Age'])
data = [['Google',10],['Runoob', 'hi'],['Wiki',13]] df = pd.DataFrame(data, columns=['Site','Age'])
总结
如果传递了 index,则索引的长度应等于数组的长度
子数组的长度应保持一致,且等于列数。如果小于列数,则对应列的数据为NaN;如果大于列数,则报错。
每一列的数据可以是不同类型。
字典
data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]} df = pd.DataFrame(data, index=['x', 'y', 'z'])
字典的value是一个list, 且每个value的list长度必须一致,否则报错。
字典的key对应DataFrame的coloum。
元素为字典的列表
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df = pd.DataFrame(data)
列表的长度可以不尽相同
没有对应的部分数据为 NaN。
属性
DataFrame.index
pandas.core.indexes.base.Index类型
DataFrame.colunms
pandas.core.indexes.base.Index类型
DataFrame.values
numpy.ndarray类型
DataFrame数据访问:
loc
返回指定行的数据,如果没有设置索引,第一行索引为 0,第二行索引为 1,以此类推。
data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 10]} df = pd.DataFrame(data, index=['x', 'y', 'z']) df.loc['x']
单行数据是一个Series
也可以返回多行数据,使用 [[ ... ]] 格式,... 为各行的索引,以逗号隔开。
data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 10]} df = pd.DataFrame(data, index=['x', 'y', 'z']) df.loc[['x', 'y']]
多行数据返回DataFrame
五、 基本功能
重新索引
reindex
reindex将会根据新索引进行重排。如果某个索引值当前不存在,就引入缺省值。
实例:
ser1 = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) ser2 = ser1.reindex(['a', 'b', 'c', 'd', 'e']) ser2
e是新引入的索引,默认缺省值是NaN
ser1 = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) ser2 = ser1.reindex(['a', 'b', 'c', 'd', 'e'], fill_value = 0) ser2
丢弃指定轴上的项
drop
对于Series可以丢弃某个或多个值;对于DataFrame可以对齐单行(列)或者多行(列)。
drop方法会返回一个新对象,原对象并未改变。
如果想在原对象上生效,令 inplace = True.
实例:
Series
ser1 = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e']) ser1 ser1.drop('c') # 丢弃索引c对应的值 ser1.drop(['d', 'c']) # 多个索引要用中括号括起来
DataFrame
data = pd.DataFrame(np.arange(16).reshape((4, 4)), columns=['Ohio', 'Colorado', 'Utah', 'New York']) data data.drop(['Colorado', 'Ohio'], axis = 1) # 删除列 data.drop([1, 2]) #删除行
数据访问
切片索引
实例:
Series
生成样例
ser1 = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
单个索引
ser1['b']
1.0
ser1[1]
1.0
这两种方式的结果是一样的,前者直接用索引访问,后者是用蕴含的整数索引访问。
切片
ser1[2:4]
前闭后开。
ser1['c':'d']
注意:标签的切片末端是包含的。
可以看出返回结果也是Series。
DataFrame
生成样例
data = pd.DataFrame(np.arange(16).reshape((4, 4)),columns=['one', 'two', 'three', 'four'], index=['a', 'b', 'c', 'd'])
切片
data[:2]
可以看出是按行切片的
data['a':'c']
注意:标签的切片末端是包含的。
返回类型仍然是DataFrame。
布尔索引
实例:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),columns=['one', 'two', 'three', 'four'], index=['a', 'b', 'c', 'd'])
data<5
可以用作mask
data[data<5]=0
True的地方执行赋值0的操作。
loc 和 iloc
介绍
Series和DataFrame都有自己的loc和iloc方法。
loc
通过标签或者布尔数组访问一组行和列。
若是布尔数组,相当于mask,true则表示提取该行或列。
iloc
与loc作用相似,只是标签用整数位置替代。
实例
生成样例
data = pd.DataFrame(np.arange(16).reshape((4, 4)),columns=['one', 'two', 'three', 'four'], index=['a', 'b', 'c', 'd'])
loc
data.loc[['a', 'b'], ['two', 'three']]
iloc
data.iloc[[0, 1], [1, 2]]
算数运算
算术方法
当两个dataframe运算时,没有重叠的位置会产生NaN。这是可以传入fill_value参数,给缺省值赋值,避免NaN。
DataFrame和Series之间的运算
默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播。换句话说就是DataFrame从上到下的每一行都和Series进行算术运算。结果是一个DataFrame。
实例:
dataframe生成
df1 = pd.DataFrame(np.arange(12).reshape(4, 3), columns=['a', 'b', 'c'])
series生成
serdata = np.random.randint(0, 10, 4) ser1 = pd.Series(serdata, index=['a', 'b', 'c', 'd'])
df1 - ser1
不重叠的位置产生NaN。
函数应用
DataFrame的apply方法可以实现将自定义的或者内建的函数应用到由各列或各行形成的一维数组上。
注意:操作的对象是一行或者一列数据。
匿名函数
样例生成
df1 = pd.DataFrame(np.arange(12).reshape(3, 4), columns=['a', 'b', 'c', 'd'])
函数定义
f = lambda x: x.max() - x.min()
注意:x是一行或者一列数据。根据函数定义可知,返回值是一个标量,即输入一个数组,输出一个标量。
f2 = lambda x: x * 2
这个函数输出也是一个数组。
df1.apply(f, axis=0)
df1.apply(f2, axis=1)
axis说明
axis=0 与 axis='index'同义。表示纵轴,即沿着行运算。
axis=1 与 axis='columns'同义。表示横轴,即沿着列运算。
普通函数
函数定义
def f3(x): return pd.Series([x.min(), x.max()], index=['min', 'max'])
每一行返回一个Series,返回当前数组的最小值和最大值。
df1.apply(f3)
df1.apply(f3, axis=1)
排序和排名
sort_index()
对行或者列索引按字典序排序
默认是升序排序,若要降序则设置参数 ascending=False
实例:
样例生成
frame = pd.DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'], columns=['d', 'a', 'b', 'c'])
frame.sort_index()
对行索引进行排序
frame.sort_index(axis=1)
对列索引进行排序
sort_values()
根据一个或多个列的值进行排序。
实例:
样例生成
df1 = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
df1.sort_values(by='b')
df1.sort_values(by=['a', 'b'])
rank()
排名值即元素在排完序后的数组中的位置,从1开始。
实例:
样例生成
frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2.5]})
插入各列的排名作为新列
frame['rank_by_b'] = frame['b'].rank() frame['rank_by_a'] = frame['a'].rank() frame['rank_by_c'] = frame['c'].rank()
带有重复值的轴索引
Series和DataFrame的索引有可能重复,索引的is_unique属性可以告诉你它的值是否是唯一的。
实例:
obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
obj.index.is_unique
False
回答的是索引是否唯一。
六、 Pandas CSV
CSV介绍
CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。
列号写在第一行。
CSV 是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。
基本操作
read_csv('name.csv')
载入CSV文件,DataFrame格式
df = pd.read_csv('nba.csv')
就这么简单!
column即CSV第一行逗号分割的列
index是从0开始的整数
to_csv('name.csv')
将 DataFrame 存储为 csv 文件
name = ['xiaoming', 'xiaohong', 'dajiang', 'laowen'] age = [15, 14, 23, 32] data = {'name': name, 'age': age} df = pd.DataFrame(data) df.to_csv('name_age.csv')
会将index也存为csv的一列,列名未命名
head(n)
读取前面的 n 行,如果不填参数 n ,默认返回 5 行
tail(n)
读取尾部的 n 行,如果不填参数 n ,默认返回 5 行
info()
返回表格的一些基本信息
七、 Pandas 数据清洗
介绍
数据清洗是对一些没有用的数据进行处理的过程。
很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况,如果要对使数据分析更加准确,就需要对这些没有用的数据进行处理。
清洗空值
识别空子段
默认情况下,read_csv会把csv文件中的以下value(不带引号)识别成NaN
‘’
‘#N/A’
‘#N/A N/A’
‘#NA’
‘-1.#IND’
‘-1.#QNAN’
‘-NaN’
‘-nan’
‘1.#IND’
‘1.#QNAN’
‘<NA>’
‘N/A’
‘NA’
‘NULL’
‘NaN’
‘n/a’
‘nan’
‘null’
na_values参数可以额外配置需要识别成NaN的值
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values)
用isnull检验是否有效识别了空子段
df['column_name'].isnull()
返回一个Series,值为布尔型,若value是NaN则为True,否则False
删除包含空字段的行
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
参数说明:
axis:默认为 0,表示逢空值剔除整行,如果设置参数 axis=1 表示逢空值去掉整列。
how:默认为 'any' 如果一行(或一列)里任何一个数据有出现 NA 就去掉整行,如果设置 how='all' 一行(或列)都是 NA 才去掉这整行。
thresh:设置需要多少非空值的数据才可以保留下来的。
subset:设置想要检查的列。如果是多个列,可以使用列名的 list 作为参数。
inplace:如果设置 True,将计算得到的值直接覆盖之前的值并返回 None,修改的是源数据。
默认情况下,dropna() 方法返回一个新的 DataFrame,不会修改源数据。如果你要修改源数据 DataFrame, 可以使用 inplace = True 参数:
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) df.dropna(inplace=True)
移除指定列有NaN的行
DataFrame.dropna()的subset参数可以配置指定的列
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) df.dropna(subset=['NUM_BEDROOMS'], inplace=True)
替换空字段
DataFrame.fillna()
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) df.fillna(-1, inplace=True)
指定某列替换空字段
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) df['NUM_BEDROOMS'].fillna(-1, inplace=True)
计算列的均值、中位数值或众数(出现频率最高的数)填充空字段
mean()
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) x = df['NUM_BEDROOMS'].mean() df['NUM_BEDROOMS'].fillna(x, inplace=True)
median()
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) x = df['NUM_BEDROOMS'].median() df['NUM_BEDROOMS'].fillna(x, inplace=True)
mode()
missing_values = ["n/a", "na", "--"] df = pd.read_csv('property-data.csv', na_values = missing_values) x = df['NUM_BEDROOMS'].mode() df['NUM_BEDROOMS'].fillna(x, inplace=True)
清洗格式错误数据
数据格式错误的单元格会使数据分析变得困难,甚至不可能。
我们可以通过包含空单元格的行,或者将列中的所有单元格转换为相同格式的数据。
格式化日期数据实例
data = {"Date": ['2020/12/01', '2020/12/02' , '20201226'], "duration": [50, 40, 45]} df = pd.DataFrame(data, index = ["day1", "day2", "day3"]) df['Date'] = pd.to_datetime(df['Date'])
格式化前
格式化后
清洗错误数据
遍历索引,处理(修改列值或删除整行)不符合条件的行。
实例:
替换错误值
person = {"name": ['Google', 'Runoob' , 'Taobao'], "age": [50, 200, 12345]} df = pd.DataFrame(person) for x in df.index: if df.loc[x, 'age'] > 120: df.loc[x, 'age'] = 120
删除错误行
person = {"name": ['Google', 'Runoob' , 'Taobao'], "age": [50, 200, 12345]} df = pd.DataFrame(person) for x in df.index: if df.loc[x, 'age'] > 120: df.drop(x, inplace=True)
清洗重复数据
duplicated()
返回DataFrame或Series,若值重复则为True,否则为False。
person = {"name": ['Google', 'Runoob', 'Runoob', 'Taobao'], "age": [50, 40, 40, 23]} df = pd.DataFrame(person) df df.duplicated()
若是DataFrame直接调用,则必须每一列的值都相同才算重复。
drop_duplicates()
删除重复的行
df df.drop_duplicates(inplace = True) df