- Python数据分析之道(Pandas)
- 一、概述
- pandas简介
- 二、基本数据访问与合并
- DataFrame的创建与访问
- iloc方法:行、列、行和列
- loc方法
- 将来自不同的DataFrame的数据合并成一个DataFrame
- merge合并DataFrame
- join方法合并DataFrame
- concat(级联)方法合并DataFrame
- 三、pandas在Hood下的工作机制
- Python数据结构
- Pandas是numpy的封装,numpy的底层是C语言
- 四、数据加载与规范化
- 输入输出函数
- 五、pandas基础数据转换
- pivot和pivot_table表
- stack 和 unstack
- melt
- 转置transpose
- 六、apply方法
- 使用场合
- 错误示例
- applu方法替换缺失数据
- 适用apply方法的示例
- 七、Groupby
- groupby目的:分组和聚合
- 索引
- 避免使用groupby
- 八、pandas之外的性能改进
- 九、pandas发展趋势
- 1、pandas是Python张处理大数据集的首选如啊年包,通常处理1GB左右的数据集,大于1GB通常建议使用其他软件库(如Vaex)
2、pandas == panel data 面板数据
基本思想:用一个较大的数据面板来平铺数据
3、Numpy:科学计算包,提供了n为数组对象来执行矩阵数学运算。Numpy是建立在c语言基础上的,所以他如此高效
numpy是pandas数据框架的底层数据结构
- 列名 都被是为一个键值,数据值作为行值返回。
DataFrame对象的构造函数允许以字典的方式创建DataFrame。
在从一个DataFrame中获取列时,是指向原始的DataFrame,在此是对原始DataFrame进行修改,有利于内存方面的性能,无须不断创建数据副本。
eg:字典语法示例
import pandas as pd
#示例2-1
account_info = pd.DataFrame({
"name":["Bob", "Mary", "Mita"],
"acount":[123344, 5656565, 343434],
"balance":[123, 345, 656],
})
account_info["name"]
0 Bob
1 Mary
2 Mita
Name: name, dtype: object
# 修改:在原表中修改的
account_info["name"] = ["Smith", 'Jane', "Patel"]
account_info
name acount balance
0 Smith 123344 123
1 Jane 5656565 345
2 Patel 343434 656
#访问多列
account_info[["name", 'balance']]
name balance
0 Bob 123
1 Mary 345
2 Mita 656
pandas不能保证字典语法返回的结果对象是视图还是副本,具有多索引或多列的DataFrame,loc方法优于字典,loc方法可以保证 *** 作的是原始DataFrame,而不是副本
iloc方法:行、列、行和列- 1、访问行,类似于列表的语法
示例2-3:利用iloc方法访问DataFrame中的行
#2-3 iloc方法:访问DataFrame的行
print(account_info.iloc[0])
print("="*60)
print(account_info.iloc[0:2])
print("="*60)
print(account_info.iloc[:])
name Bob
acount 123344
balance 123
Name: 0, dtype: object
============================================================
name acount balance
0 Bob 123344 123
1 Mary 5656565 345
============================================================
name acount balance
0 Bob 123344 123
1 Mary 5656565 345
2 Mita 343434 656
2、访问列,iloc函数中的第一个位置是指定行索引,第二个位置是指定列索引
示例2-4:利用iloc来访问 行 和 列
#2-4 使用iloc访问行和列
print(account_info.iloc[0,2])
print("="*60)
account_info.iloc[0,2] = 1111
print(account_info.iloc[0,2])
print("="*60)
print(account_info.iloc[:,[0,2]])#所有行,第0,1,列前闭后开区间
123
============================================================
1111
============================================================
name balance
0 Bob 1111
1 Mary 345
2 Mita 656
3、iloc方法也允许使用布尔数组,通过取每一行索引的模并将其转化为布尔值来获取所有奇数行
示例2-5:iloc方法访问行和列
# 2-5
account_info.iloc[account_info.index % 2 ==1]
name acount balance
1 Mary 5656565 345
4、iloc方法也允许一个函数输入,略
5、使用iloc方法从 多索引 多列 (组的形式,两个行索引,两个列索引) DataFrame中提取子DataFrame
(没太理解 )
- loc方法与iloc类似,loc方法还允许通过列名或标签对DataFrame进行索引(一个用“” 多个传入list [“”, “” ])
示例2-7:
# 2-7
print(account_info.loc[1,"balance"])
print("="*60)
print(account_info.loc[:,["name","balance"]])
345
============================================================
name balance
0 Bob 1111
1 Mary 345
2 Mita 656
df = df.pivot_table(
values = ["score"],
index = ["restaurant", "location"],
aggfunc = np.mean,# 默认也是np.mean
)
df = df[["score"]].groupby(["restaurant", "location"]).mean()
示例2-8:使用loc方法从 多索引列 多列 (组的形式,两个行索引,两个列索引)DataFrame中提取DataFrame
acc.loc[(“Mary”,“mj100”), pd.IndexSlice[:, “balance”] ]
- merge与数据库中的join工作方式相同
外归并(outer):并集,将两组基因样本的数据集合在一起,空值为Nan
pd.merge(表1, 表2, how=outer’, on=[‘合并两个表依据的列名’], )
内归并(inner):交集
pd.merge(表1, 表2, how=‘inner’, on=[‘合并两个表依据的列名’], )
左归并(left):
pd.merge(表1,表2,how=“left”,right_on=“building”, left_on = “building”, suffixes(“_ex”,“” ))suffix参数提供新的列名便于区分
右归并(riht):本质与左归并相同,只是将DataFrame以相反顺序传入。
示例2-13:非常规合并,计划进行第3次医学实验,只有参加过前两次实验其中一次的患者(只能参加过其中一次)才有资格参加第三次
pandas的合并方法中提供了一个名为indicator=False的参数,用于在生成DataFrame中添加名为_merge的附加列,表明键值是否在left_only, right_only, both
pd.merge(表1,表2,how='outer', indicator=True, right_index=True, left_index=True, on="name",)
.query('_merge'!="both").drop('merge', 1)
- 合并两个具有相同数据的DataFrame,且两个表没有重复列,,只是简单合并,merge要优于join,join方法是在底层调用merge
- join允许在多索引DataFrame上自动执行合并 *** 作,无需指定待合并列的索引,
左连接时:join方法默认在左侧的FataFrame索引上执行合并(传入的参数不同)
- pd.concat([表1,表2])简单堆叠,上下相连,有重复的
- 使用多列concat啊方法连接两个DataFrame
pd.concat([表1,表2],
keys=["新列名1", "新列名2"],
axis = 1, )
axis 指明是竖着拼接or横着连接
三、pandas在Hood下的工作机制
Python数据结构
- 元组:很多方面都相当于C语言的数组。
元组的值创建后就不能改变
索引(指向内存中实际值所在地址的指针),值
元组可迭代,即可通过循环遍历查看其中的每个值 - 列表:简单地说,列表是一个可变的元组
底层是一个固定大小的数组(2的倍数),元素数量超限时,创建一个新的数组,并将旧数组中的元素复制到新数组中。 - 字典:字典本质是一个哈希表
根据字典中键值的数量,利用散列的特定位数来确定索引 - 集合:集合的结构和字典基本相同,但没有数据值
集合是用于跟踪成员关系的数据结构,可执行数学集合论中几乎所有的运算,如交集并集等 - 整数、浮点是、布尔数、字符串
python有整数和字符串缓存,即两个相同的在内存中可能只存放了一份
- read_… / to_…
read_csv()/ to_csv()
输入函数都提供了数据规范化的各种选项,如允许加载过程中删除,指定各列的数据类型,加载指定范围内的数据等等
pandas通常会爱加载数据时推断数据类型,许多加载函数允许指定列的数据类型 - 将各种数据加载/输出到DataFrame中,
csv, excel, hdf, hdf, json, html, stata, clipboard, pickle等 - read_csv( path = “”, sep=“”, engine= , usecols=“”/[“”, “”])
path:文件存放的路径,
sep:分隔数据符,逗号,I,空格等
usecols: 指定某些列,一列用"“, 多列用[”“, “”]
skipfooter:允许跳过文件中的某些行,跳过前n行,跳过指定的n行
coment:用户指定表示注释的字符
默认情况下第一行视为数据头
header =[0, 1] 多索引行,
如果数据包含多列,可通过参数header指定将哪些行号视为列
index_col =”"/[0]/[0, 1]多索引列
可通过列索引指定哪些列看成是多索引的一部分
squeeze:默认是false, 若启动squeeze,当DataFrame只有一列时,返回Series,在多个源加载数据并将其合并到单个DataFrame中时非常有用
dtype:允许对每一列指定一种类型,如未指定,pd将自己推断
nrows:加载前多少行
converters:参数指定一个函数来转化特定列中得知,如 某列中有表示同一值的多个值,希望将其规范化为单个值(通常借助函数来转换
)
利用参数nrows、skiprows和header结合,有利于将文件分块读入内存并进行处理,然后读取下一个块。
-
pd.read_json()
orient的split应用:pd.read_json(data, orient=“split”)
orient的records、index、columns、values、table应用
read_json也具有允许分开读取文件的chunksize,但只有lines选项设为true时才允许, pd.read_json(data, lines=True, chunksize=2) -
其他read_函数,随用随查
- 功能很强大,功能强大是性能下降为代价的
不应频繁使用
pivot本质上实质性groupby *** 作,根据需要执行聚合函数,并将结果重新组织未新的表格格式。
示例5-1:利用pivot表计算灭个餐馆的平均检查得分。
df = df.pivot_table(# pivot表
values = ["score"],
index = ["restaurant", "location"],
aggfunc = np.mean,# 默认也是np.mean
)
等价于
df = df[["score"]].groupby(["restaurant", "location"]).mean()
- pivot作用与pivot表相同,但不允许聚合数据
df.pivot(
index = "drug",
columns = "date",
values = "tumor_size",
)
当索引和列的组合具有多个值时,pivot和pivot表不会输出数据,pivot表可以强制将多个值聚合,或者选择其中一个值,二pivot只会出现一个ValueError(值错误)。
但当 在同一列和索引的组合具有多个值时,pivot会产生一个ValueError(值错误):ValueError:Index contains duplicate entries, cannot reshape
- stack:将DataFrame的列级重组为一个最内部的索引,
stack用于重组数组,使得每个餐馆的卫生检查的得分是在每一行而不是每一列
stack需要复制内存,所以代价较大 - 聚合函数 groupby, 其实很多方法都是建立在groupby之上,
- 功能与stack基本相同,但在内存开销方面优势明显
- 将列转换为行,将行转换为列
df.transpose(copy=False/True) copy 指明是否需要复制数据
- apply是pandas中最容易错误使用的函数之一,apply时将函数“应用”到数据集中的每一行或每一列,违反了pandas的一条基本准则:不得迭代执行数据集。
别瞎用就是了
-
df.apply(np.sum, axis =1)
得到各行之和,调用sum函数,指定应用该函数的axis,
但这是错误的,因为np.sum函数是DataFrame本身的内置函数,应该直接使用内置函数这样更有效! -
等价于 df.sum(axis = 1)
pandas的内置sum函数要优于对每一行数据执行Numpy的sum函数,对每一行相当于对数据行执行迭代,
6-2 pandas中apply方法实现的主循环
for i, v in enumerate(series_gen):
results[i] = self.f(v)
keys.append(v.name)
applu方法替换缺失数据
#- 6-5
def replace_missing(series):
if np.isnan(series["A"]):
series["A"] = max(series["B"], series["C"])
return series
df = df.apply(replace_missing, axis=1)
#- 6-6 采用where方法替换缺失数据
where方法是采用第二个参数中的值来替换错误值
df["A"].where(
~df["A"].isna(),
df[["B","C"]].max(axis=1),
inplace=True,
)
inplace = True, 使得只是在当前DataFrame进行替换,而不是创建一个会导致重复占用内容的新DataFrame
#6-7 使用apply方法删除order列中不包含fruit列中字串的数据行
适用apply方法的示例
七、Groupby
groupby目的:分组和聚合
groupby是将数组分组,然后对每组数据运行聚合函数,实际上是对各个数据组执行循环,效率较低,不如执行简单的按行或列 *** 作更有效
group= arr.groupby([“date”, “place”]).sum()
- 使用排序的多索引
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)