博文转载:https://www.runoob.com/pandas/pandas-tutorial.html
基于NumPy的一种工具,该工具是为解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。
Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。
Pandas 可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。
Pandas 广泛应用在学术、金融、统计学等各个数据分析领域。
Pandas 应用Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。
数据结构Series 是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
二、Pandas 安装
安装 pandas 需要基础环境是 Python,开始前我们假定你已经安装了 Python 和 Pip。
使用 pip 安装 pandas:
pip install pandas
安装成功后,我们就可以导入 pandas 包使用:
import pandas as pd # 实例 - 查看 pandas 版本 pd.__version__ # 查看版本 #一个简单的 pandas 实例: mydataset={ '第一列':['蔬菜','琴台','早上'], '第二列':['肉禽','笔墨','篝火'] } myvar = pd.DataFrame(mydataset) print(myvar)
三、Pandas 数据结构 - Series
Pandas Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型。
Series 由索引(index)和列组成,函数如下:
pandas.Series( data, index, dtype, name, copy)
参数说明:
data:一组数据(ndarray 类型)。
index:数据索引标签,如果不指定,默认从 0 开始。
dtype:数据类型,默认会自己判断。
name:设置名称。
copy:拷贝数据,默认为 False。
sites = {1: "Google", 2: "Runoob", 3: "Wiki"} myvar = pd.Series(sites, index = [1, 2])
#如果没有指定索引,索引值就从 0 开始: print(myvar) print(myvar[1]) # 我们可以指定索引值,如下实例: ar = ['a','b','c'] myvar = pd.Series(ar,index=['x','y','z']) print(myvar) # 根据索引值读取数据: print(myvar['y'])
我们也可以使用 key/value 对象,类似字典来创建 Series:
实例:
import pandas as pd sites = {1: "Google", 2: "Runoob", 3: "Wiki"} myvar = pd.Series(sites) print(myvar)
设置 Series 名称参数:
import pandas as pd sites = {1: "Google", 2: "Runoob", 3: "Wiki"} myvar = pd.Series(sites, index = [1, 2], name="RUNOOB-Series-TEST" ) print(myvar)
四、Pandas 数据结构 - 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。
Pandas DataFrame 是一个二维的数组结构,类似二维数组。
实例 - 使用列表创建import pandas as pd data = [['Google',10],['Runoob',12],['Wiki',13]] df = pd.DataFrame(data,columns=['Site','Age'],dtype=float) print(df)
以下实例使用 ndarrays 创建,ndarray 的长度必须相同, 如果传递了 index,则索引的长度应等于数组的长度。如果没有传递索引,则默认情况下,索引将是range(n),其中n是数组长度。
实例 - 使用 ndarrays 创建import pandas as pd data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]} df = pd.DataFrame(data) print (df)
从以上输出结果可以知道, DataFrame 数据类型一个表格,包含 rows(行) 和 columns(列):
还可以使用字典(key/value),其中字典的 key 为列名:
实例 - 使用字典创建import pandas as pd data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df = pd.DataFrame(data) print (df)
输出结果为:
a b c
0 1 2 NaN
1 5 10 20.0
没有对应的部分数据为 NaN。
Pandas 可以使用 loc 属性返回指定行的数据,如果没有设置索引,第一行索引为 0,第二行索引为 1,
以此类推:
data = { "calories": [420, 380, 390], "duration": [50, 40, 45] } # 数据载入到 DataFrame 对象 df = pd.DataFrame(data) # 返回第一行 print(df) print(df.loc[0]) ''' #返回结果其实就是一个 Pandas Series 数据。 calories 420 duration 50 Name: 0, dtype: int64 '''
#返回第一行和第二行
#返回多行数据,使用 [[ ... ]] 格式,... 为各行的索引,以逗号隔开:
print(df.loc[[0,1]])
''' 返回结果其实就是一个 Pandas DataFrame 数据。
calories duration
0 420 50
1 380 40
'''
只拿mango这一列的数据
data = { "calories": [420, 380, 390], "duration": [50, 40, 45] } df = pd.DataFrame(data, index = ["day1", "day2", "day3"]) print(df) ''' calories duration day1 420 50 day2 380 40 day3 390 45 ''' # Pandas 可以使用 loc 属性返回指定索引对应到某一行: # 指定索引 print(df.loc["day2"]) ''' calories 380 duration 40 Name: day2, dtype: int64 '''
data = { "mango": [420, 380, 390], "apple": [50, 40, 45], "pear": [1, 2, 3], "banana": [23, 45,56] } df = pd.DataFrame(data) print(df[['mango']]) #只拿mango这一列的数据 # 假设我们只关注 apple列 和 banana列 的数据时,可以使用以下方法: print(df) print(df[["apple","banana"]])
五、Pandas CSV 文件
CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。
CSV 是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。
Pandas 可以很方便的处理 CSV 文件,本文以 nba.csv 为例
dt = pd.read_csv('./nba.csv') #to_string() 用于返回 DataFrame 类型的数据,如果不使用该函数,则输出结果为数据的前面 5 行和末尾 5 行,中间部分以 ... 代替。 print(dt.to_string()) print(dt) print(dt.loc[1]) #获取第一行数据 print(dt[['Name']]) # 获取Name列的数据#我们也可以使用 to_csv() 方法将 DataFrame 存储为 csv 文件:
#定义三个字段的数据 name = ['zs','ls','ww'] age = [18,19,20] gender = ['男','男','男'] #定义字典 dt = {'names':name,'ages':age,'genders':gender} #转化为dataframe结构 dt = pd.DataFrame(dt) print(dt) #保存为csv文件 默认生成位置为当前项目 可写绝对路径改变生成位置 dt.to_csv('test.csv') dt.to_csv('C:/test.csv')数据处理
head()
head( n ) 方法用于读取前面的 n 行,如果不填参数 n ,默认返回 5 行。下标0开始
df = pd.read_csv('nba.csv')
print(df.head(10))
tail()tail( n ) 方法用于读取尾部的 n 行,如果不填参数 n ,默认返回 5 行,空行各个字段的值返回 NaN。
print(df.tail(10))
info()info() 方法返回表格的一些基本信息: df = pd.read_csv('nba.csv') print(df.info()) df = pd.read_csv('nba.csv') print(df.info())
'''六、Pandas JSON
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 458 entries, 0 to 457 # 行数,458 行,第一行编号为 0
Data columns (total 9 columns): # 列数,9列
# Column Non-Null Count Dtype # 各列的数据类型
--- ------ -------------- -----
0 Name 457 non-null object
1 Team 457 non-null object
2 Number 457 non-null float64
3 Position 457 non-null object
4 Age 457 non-null float64
5 Height 457 non-null object
6 Weight 457 non-null float64
7 College 373 non-null object # non-null,意思为非空的数据
8 Salary 446 non-null float64
dtypes: float64(4), object(5) # 类型
'''
#non-null 为非空数据,我们可以看到上面的信息中,总共 458 行,College 字段的空值最多。
JSON(JavaScript Object Notation,JavaScript 对象表示法),是存储和交换文本信息的语法,类似 XML。
JSON 比 XML 更小、更快,更易解析,
Pandas 可以很方便的处理 JSON 数据,本文以 sites.json 为例,内容如下:
import pandas as pd df = pd.read_json('sites.json') print(df.to_string()) #to_string() 用于返回 DataFrame 类型的数据,我们也可以直接处理 JSON 字符串。 df = pd.DataFrame(df) print(df)
以上实例输出结果为:
id name url likes
0 A001 菜鸟教程 www.runoob.com 61
1 A002 Google www.google.com 124
2 A003 淘宝 www.taobao.com 45
JSON 对象与 Python 字典具有相同的格式,所以我们可以直接将 Python 字典转化为 DataFrame 数据:
实例# 定义字典 s = { "col1":{"row1":1,"row2":2,"row3":3}, "col2":{"row1":"x","row2":"y","row3":"z"} } # 读取 JSON 转为 DataFrame df = pd.DataFrame(s) print(df) #从 URL 中读取 JSON 数据: URL = 'https://static.runoob.com/download/sites.json' df = pd.read_json(URL) print(df)内嵌的 JSON 数据
假设有一组内嵌的 JSON 数据文件 sites2
df = pd.read_json('sites2.json')
print(df)
以上实例输出结果为: school_name class students 0 ABC primary school Year 1 {'id': 'A001', 'name': 'Tom', 'math': 60, 'phy... 1 ABC primary school Year 1 {'id': 'A002', 'name': 'James', 'math': 89, 'p... 2 ABC primary school Year 1 {'id': 'A003', 'name': 'Jenny', 'math': 79, 'p... 这时我们就需要使用到 json_normalize() 方法将内嵌的数据完整的解析出来:
import json with open('sites2.json','r') as f: print('aaa') data = json.loads(f.read()) #data = json.loads(f.read()) 使用 Python JSON 模块载入数据。 #json_normalize() 使用了参数 record_path 并设置为 ['students'] 用于展开内嵌的 JSON 数据 students。 df = pd.json_normalize(data,record_path=['students']) print(df)
七、Pandas 数据清洗
数据清洗是对一些没有用的数据进行处理的过程。
很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况,如果要对使数据分析更加准确,就需要对这些没有用的数据进行处理。
在这个教程中,我们将利用 Pandas包来进行数据清洗。
本文使用到的测试数据 数据清洗.csv :
Pandas 清洗空值
如果我们要删除包含空字段的行,可以使用 dropna() 方法,语法格式如下:
#我们可以通过 isnull() 判断各个单元格是否为空。 df = pd.read_csv('./数据清洗.csv') print(df['NUM_BEDROOMS']) print(df['NUM_BEDROOMS'].isnull())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,修改的是源数据。
missing_values= ['n/a','na','--'] df = pd.read_csv('./数据清洗.csv',na_values=missing_values) print (df['NUM_BEDROOMS']) print (df['NUM_BEDROOMS'].isnull())#接下来的实例演示了删除包含空数据的行
df = pd.read_csv('./数据清洗.csv') df = df.dropna() print(df.to_string())#注意:默认情况下,dropna() 方法返回一个新的 DataFrame,不会修改源数据。
#如果你要修改源数据 DataFrame, 可以使用 inplace = True 参数:
df = pd.read_csv('./数据清洗.csv') df.dropna(inplace = True) print(df.to_string())
#我们也可以移除指定列有空值的行:
#移除 ST_NUM 列中字段值为空的行:
df = pd.read_csv('./数据清洗.csv') df.dropna(subset=['ST_NUM'], inplace = True) print(df.to_string())我们也可以 fillna() 方法来替换一些空字段:
df = pd.read_csv('./数据清洗.csv') df=df['PID'].fillna(11) #使用 12345 替换 PID 为空数据 df =df.fillna(12345) #使用 12345 替换全表为空数据 print(df.to_string())#替换空单元格的常用方法是计算列的均值、中位数值或众数。
#Pandas使用 mean()、median() 和 mode() 方法计算列的均值(所有值加起来的平均值)、中位数值(排序后排在中间的数)和众数(出现频率最高的数)。
#使用 mean() 方法计算列的均值并替换空单元格: df = pd.read_csv('./数据清洗.csv') x = df["ST_NUM"].mean() df["ST_NUM"].fillna(x, inplace = True) print(df.to_string()) #使用 median() 方法计算列的中位数并替换空单元格: df = pd.read_csv('./数据清洗.csv') x = df["ST_NUM"].median() df["ST_NUM"].fillna(x, inplace = True) print(df.to_string()) #使用 mode() 方法计算列的众数并替换空单元格: df = pd.read_csv('./数据清洗.csv') x=df['NUM_BATH'].mode() print('---',x) #--- 0 1 默认输出x 为 0 1 print("-----",int(x)) # ----- 1 强转 dt = df['ST_NUM'].fillna(float(x)) # 强转 print(dt.to_string())Pandas 清洗格式错误数据
数据格式错误的单元格会使数据分析变得困难,甚至不可能。
我们可以通过包含空单元格的行,或者将列中的所有单元格转换为相同格式的数据。
以下实例会格式化日期:
# 第三个日期格式错误 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']) print(df.to_string())
以上实例输出结果如下:
name age 0 Google 50 1 Runoob 40 2 Taobao 30
也可以设置条件语句:
实例将 age 大于 120 的设置为 120:
import pandas as pd 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 print(df.to_string())
以上实例输出结果如下:
name age 0 Google 50 1 Runoob 120 2 Taobao 120
也可以将错误数据的行删除:
将 age 大于 120 的删除:
import pandas as pd person = { "name": ['Google', 'Runoob' , 'Taobao'], "age": [50, 40, 12345] # 12345 年龄数据是错误的 } df = pd.DataFrame(person) for x in df.index: if df.loc[x, "age"] > 120: df.drop(x, inplace = True) print(df.to_string())
以上实例输出结果如下:
name age 0 Google 50 1 Runoob 40Pandas 清洗重复数据
如果我们要清洗重复数据,可以使用 duplicated() 和 drop_duplicates() 方法。
如果对应的数据是重复的,duplicated() 会返回 True,否则返回 False。
import pandas as pd person = { "name": ['Google', 'Runoob', 'Runoob', 'Taobao'], "age": [50, 40, 40, 23] } df = pd.DataFrame(person) print(df.duplicated())
以上实例输出结果如下:
0 False 1 False 2 True 3 False dtype: bool
删除重复数据,可以直接使用drop_duplicates() 方法。
import pandas as pd persons = { "name": ['Google', 'Runoob', 'Runoob', 'Taobao'], "age": [50, 40, 40, 23] } df = pd.DataFrame(persons) df.drop_duplicates(inplace = True) print(df)
以上实例输出结果如下:
name age
0 Google 50
1 Runoob 40
3 Taobao 23