数据分析从0到1----Pandas篇(一)

简介: 数据分析从0到1----Pandas篇

前言

阅读文本前要求读者了解jupyter如何使用,以及python的基础语法,同时还要求读者了解基本的numpy和matplotlib函数.如果不了解两个包的语法,可以大致学习一下.

Numpy篇

Matplotlib篇

什么是Pandas?

Pandas官方文档

Series

Series结构

Series结构,也称Series序列,是Pandas常用的数据结构之一,它是一种类似于一维数组的结构,由一组数据值(value)和一组标签组成,其中标签与数据值具有对应关系。

标签不必是唯一的,但必须是可哈希类型。该对象既支持基于整数的索引,也支持基于标签的索引,并提供了许多方法来执行涉及索引的操作。ndarray的统计方法已被覆盖,以自动排除缺失的数据(目前表示为NaN)

Series 可以保存任何数据类型,比如整数、字符串、浮点数、Python对象等,它的标签默认为整数,从0开始依次递增。Series的结构图,如下所示:

pd.Series(data=None,index=None,dtype=None,name=None,copy=False)

  • data输入的数据,可以是列表、常量、ndarray数组等,如果是字典,则保持参数顺序
  • index索引值,必须是可散列的(不可变数据类型(str, bytes和数值类型)),并且与数据具有相同的长度.允许使用非唯一索引值。如果未提供,将默认为Rangelndex (0,1,2…,n)
  • dtype输出系列的数据类型。如果未指定,将从数据中推断.
  • name为Series定义一个名称
  • copy表示对data进行拷贝,默认为False,仅影响Series和ndarray数组

先简单的创建一个Series

list = [1,2,True,'str',1.0]
index = [0,1,4,2,3] # 设定对应的数组位置的数据索引为该索引 例如本来True索引为2,这里变为4
s=pd.Series(list,index=index)# 使用index并不会修改原series中数据的顺序
print(s[4]) # 只是使用下标访问的时候数据顺序与放进去的list集合不一样而已
print(s.values)
print(s.index) # 获取元素对应索引
s[0]=10
print(s)
# print(s[-1]) # 会报错,Series默认找的是标签,而不是下表,因此不能使用负值,他不能从后往前走
s[-1]=100 # 但是如果向里面添加-1这个标签,那么下次就可以访问-1并且不会报错
s['a']='abcde'
print('s[a]====',s['a'])
print(s)

Series的数据可以使用标签进行访问,如果标签为非全数字,那么也可以使用标签对应的索引进行访问

list = {'a': 1,'b':2,'c':3} # 直接传入一个字典变为Series
s = pd.Series(list)
print(s)
print(s.index)
print(s.values)
print(s['a'])
s['d']=4 # 添加一个标签d-->4
print(s[3]) # 可以使用标签对应的下标去取对应的数据

data = ['a','b','c','d']
s = pd.Series(data,index=[1,2,3,4])
print(s)
# print(s[-1]) # 因为index索引为全数字,那么此时的检索方法为标签检索,因此无法使用下标进行检索
s[-1]=-1 # 但是你还是可以继续添加元素'
s = pd.Series(data,index=['a','b','c',4])
print(s)
print(s[-1]) # 此时索引为非全数字,那么就可以使用索引进行访问

现在来介绍一下name这个属性

data = {
    "one":1,
    "two":2,
    "three":3
}
num = pd.Series(data)
num.name = 'num_data'
num.index.name = 'num_name'
print(num)
print('----------')
df = pd.DataFrame(num)
print(df,type(df))
print('----------')
print(df['num_data'],type(df['num_data']))

现在来介绍copy这个参数

# copy表示队data进行拷贝,默认为False,仅影响Series和ndarray数组
# 也就是如果你的data来自于ndarray,那么你对Series数据的修改也会修改对应的ndarray数组
data = np.arange(1,6)
s = pd.Series(data)
s[1]=10 # 修改Series的值
print(s) 
print(data)# 可以发现data的值居然也被修改了

# 如果数据源来自于非Series和ndarray类型
list = [1,2,3,4]
s = pd.Series(list)
s[1]=10
print(s)
print(list) # 可以发现list并没有杯修改

Series的索引与切片

这里应该自己多编写代码进行测试来帮助自己了解索引和切片

s = pd.Series(np.random.rand(5),index=['h','x','s','b','n'])
# 进行切片运算
print(s[1:3]) # 使用索引不包含end
print(s[-3:]) # 从-3开始向后切片
print(s[-3::-1]) # 从-3开始向前切片
print(s[::])
print(s['s':'n']) # 甚至可以使用标签进行切片 包含end 从s开始知道找到标签n
# 如果数据源来自于非Series和ndarray类型
list = [1,2,3,4]
s = pd.Series(list,index=[1,2,3,4])
s[1]=10
print(s[-1])#索引类型为数字的时候,此时位置索引失效,使用的为标签索引
# 如果没有找到-1这个标签,那么就报错
print(list) # 可以发现list并没有杯修改

注意:

在上面的索引方式,我们知道了位置索引和标签索引在index为数值类型时候的不同,

  • 当index为数值类型的时候,使用位置索引会抛出keyerror的异常,也就是说当index为数值类型的时候,索引使用的是名称索引。
  • 但是在切片的时候,有很大的不同,如果index为数值类型的时候,切片使用的是位置切片。总的来说,当index为数值类型的时候:
  • 进行索引的时候,相当于使用的是名称索引;
  • 进行切片的时候,相当于使用的是位置切片;

head/tail

这两个方法用于查看Series头尾数据,默认都是5条

s = pd.Series(np.random.rand(10))
print(s.head()) # 默认查看头5条数据
print(s.head(1)) # 查看头1条数据
print(s.tail()) # 默认查看尾5条数据
print(s.tail(1)) # 查看尾1条数据

reindex

用于重新设定Series的index索引

s = pd.Series(np.random.rand(5),index=['h','x','s','b','n'])
print(s)
s1 = s.reindex(['a','b','c','d','e']) # 以返回一个新的Series的形式新建index,因为这样效率更高
# 同时只有原索引和新索引中拥有重复的索引名称的时候对应的值才会被赋予,否则为NaN
print(s1)
s2=s1.reindex(['g','e','f'],fill_value=0) # 重定义索引之后如果被赋予了NaN,那么fill_value可以填充其为对应的值
# 例如这里由于s1和s2中都有e,但是原来的s1中的e本来就为NaN所以并不会被赋予0.0
# 而g和f都是s1原来没有的,因此他们的NaN会变为0.0
print(s2)

对齐运算

是数据清洗的重要过程,可以按索引/标签对齐进行运算,如果没对齐的位置则补NaN,最后也可以填充NaN.

s1 = pd.Series(np.random.rand(3),index=['a','b','c'])
s2 = pd.Series(np.random.rand(3),index=['b','a','h'])
print(s1)
print(s2)
print(s1+s2) # 可以发现没有对齐的数据直接被赋予了NaN

添加删除

s = pd.Series(np.random.rand(5),index=['a','b','c','d','e'])
print(s)
s1 = s.drop('c',inplace=True) # 在原值上发送变化,返回None
s['f']=100 # 进行添加 如果没有标签f 那么就添加 有就修改
print(s1)
print(s)

DataFrame

DataFrame是Pandas 的重要数据结构之一,也是在使用Pandas进行数据分析过程中最常用的结构之一,可以这么说,掌握了DataFrame 的用法,你就拥有了学习数据分析的基本能力。|

DataFrame是一个表格型的数据结构,既有行标签(index),又有列标签(columns),它也被称异构数据表,所谓异构,指的是表格中每列的数据类型可以不同。比如可以是字符串、整型或者浮点型等。其结构图示意图,如下所示:

DataFrame的每一列数据都可以看成一个Series结构,只不过,DataFrame为每列数据值增加了一个列标签。因此DataFrame其实是从 Series的基础上演变而来,并且他们有相同的标签,在数据分析任务中 DataFrame的应用非常广泛,因为它描述数据的更为清晰、直观。

同Series一样,DataFrame自带行标签索引,默认为“隐式索引"即从0开始依次递增,行标签与DataFrame 中的数据项一 一对应。当然你也可以用"显式索引的方式来设置行标签。

下面对 DataFrame数据结构的特点做简单地总结,如下所示:

  • DataFrame每—列的标签值允许使用不同的数据类型;
  • DataFrame是表格型的数据结构,具有行和列;
  • DataFrame 中的每个数据值都可以被修改。
  • DataFrame结构的行数、列数允许增加或者删除;
  • DataFrame有两个方向的标签轴,分别是行标签和列标签;
  • DataFrame可以对行和列执行算术运算。

pandas. DataFrame (data=None,index=None,columns=None,dtype=None,copy=None)

  • data:输入的数据,可以是ndarray,series, list,dict,标量以及一个 DataFrame
  • index:行标签,如果没有传递 index值,则默认行标签是RangeIndex(0,1,2… n),n代表data的元素个数。
  • columns:列标签,如果没有传递columns值,则默认列标签是RangeIndex(0,1,2,… n)。
  • dtype:要强制的数据类型。只允许使用一种数据类型。如果没有,自行推断
  • copy:从输入复制数据。对于dict数据,copy=True,重新复制一份。对于DataFrame或ndarray输入,类似于copy=False,使用的是视图

最基本的,使用列表嵌套列表创建DataFrame

df = pd.DataFrame([[1,'大少',12],[2,'太君',16]],index=[1,2],columns=['学号','名字','年龄'])
print(df)

之后就是使用列表掏钱字典创建

df = pd.DataFrame(data=[{'a':1,'c':3},{'a':2,'b':3}],index=['one','two'])
print(df)  # 取交集进行显示
df = pd.DataFrame(data=[{'a':1,'c':3},{'a':2,'b':3}],index=['one','two'],columns=['a','b','d'])
# 因为d这一列压根就没有对应的元素,所以直接全为NaN
print(df)  # 取交集进行显示

使用字典嵌套列表的方式进行创建

data={ 'Name':['a','b','c','d'] , 'Age':[1,2,3,4]  }
df = pd.DataFrame(data,index=['one','two','three','four'])
print(df)
print(df.index)
print(df.columns)

也可以使用Series创建DataFrame对象

# 如果使用这种形式,其实是吧name对应的索引名字改为了1 2 3 
# 而其他的几个属性的索引还是 0 1 2 因此就会导致数据不对应
# d = {'name':pd.Series(['zhang','wang','li'],index=[1,2,3]),
d = {'name':pd.Series(['zhang','wang','li']),
    'age':pd.Series([20,30,40],dtype=float),
    'sex':pd.Series(['nan','nv','nan']),
    'money':pd.Series([10,20,30],dtype=float)}
df = pd.DataFrame(d) # 你可以试着在不同的属性上添加上index
print(df) # 这里one虽然显示了对应的索引d,但是由于没给数据,因此直接NaN

了解了如何创建DataFrame,之后就要了解如何增删改查DataFrame了

首先进行对DataFrame列的操作

下面先进行的是列的选取操作

# 选取对应数据列
data={ 'Name':['a','b','c','d'] , 'Age':[1,2,3,4]  }
df = pd.DataFrame(data,index=['one','two','three','four'])
print(df)
print('---获取Name列-----')
print(df['Name'])
print('---获取Age列-----')
print(df['Age'])
print('---获取Name和Age列-----')
print(df[['Name','Age']])
print('---获取某一列数据------')
print(df['Name']['one'])
print('---遍历某一列数据------')
for i in df['Name']:
    print(i)

接下来是添加操作

d = {'one':pd.Series([2,3,4,5],index=['a','b','c','d']),
    'two':pd.Series([20,30,40],index=['a','b','c'])}
df = pd.DataFrame(d) # 你可以试着在不同的属性上添加上index
print(df)
print('---获取某一列数据------')
df['three']=pd.Series([5,6,7],index=['a','b','c'])
print(df)
print('---获取某一列数据------')
df['four']=df['one']+df['three']
print(df)

d = {'one':pd.Series([2,3,4,5],index=['a','b','c','d']),
    'two':pd.Series([20,30,40],index=['a','b','c'])}
df = pd.DataFrame(d) # 你可以试着在不同的属性上添加上index
print(df)
print('---获取某一列数据------')
# 使用insert添加,第一个参数表示要插入到的位置,0<=loc<=len(列)
# 第二个参数为添加后的列名标签
# 第三个表示要插入到该列的值
# 第四个表示是否允许列名重复
df.insert(2,column='three',value=[1,2,3,4])
print(df)

最后是删除操作

d = {'one':pd.Series([2,3,4,5],index=['a','b','c','d']),
    'two':pd.Series([20,30,40],index=['a','b','c'])}
df = pd.DataFrame(d)
df.insert(2,column='three',value=[1,2,3,4])
print(df)
print('---获取某一列数据------')
del df['one'] # 使用del删除某一列
print(df)
print('---获取某一列数据------')
del_data=df.pop('two') # 使用pop删除某一列数据
print(df)
print('---pop删除会返回被删除的数据------')
print(del_data)

列操作结束之后,来进行DataFrame的行操作

行操作相对于列操作,就不能直接使用[]进行访问,而需要使用loc进行访问

loc使用的是标签名称进行访问,他的访问方式很类似与numpy中的一些语法,但是又有所不同

例如df.loc[[‘a’,‘b’],[‘c’,‘d’]]他访问的是行标签名称为a和b的两行,且列标签为c和d的两列,也就是最后会返回2*2个数据

而np[[0,1],[1,2]]访问的则是索引为(0,1)和(1,2)的,也就是他遵循的是一一对应原则,而不是loc中的一行对一列原则.

d = {'one':pd.Series([2,3,4,5],index=['a','b','c','d']),
    'two':pd.Series([20,30,40],index=['a','b','c'])}
df = pd.DataFrame(d)
print(df)
print('显示行b上的所有数据')
print(df.loc['b'])
print('注意loc的两个参数分别是行和列')
print(df.loc['b','one'])
print('行和列还可以使用切片')
print(df.loc['b':'d','one':'two']) # 行截取b--d 列选取one与two
print('第一个参数代表代表行,第二个参数代表列')
print(df.loc[['a','b'],['one','two']])# 获得行索引为a和b且列索引为one和two的数据 展示的数据量为rows*cols
# DataFrame和numpy数组是有区别的
s=np.arange(12).reshape((3,4))
print(s)
print(s[[0,1],[1,2]]) # 获取(0,1),(1,2)

如果不想使用标签进行访问,那么可以使用iloc方法,iloc方法直接使用索引,会优先查找的是行标签,如果找不到就会报错.

特别注意:
loc只能使用标签进行搜索,使用索引会报错
iloc只能使用索引来进行搜索,使用标签就会报错

d = {'one':pd.Series([2,3,4,5],index=['a','b','c','d']),
    'two':pd.Series([20,30,40],index=['a','b','c'])}
df = pd.DataFrame(d)
print(df)
print('-------')
print(df.iloc[2]) # 查找第二行上的数据
print('-------')
print(df.iloc[[1,2,3]])# 查找索引为1,2,3行上的数
print('-------')
print(df.iloc[0,1]) # 查找第0行第1列上的数据
# 这里等同于
print(df.loc['a']['two'])
# print(df.iloc['a']['two']) # iloc只能使用数值 因此使用标签查找会报错
# print(df.loc[0,1]) # loc只能使用标签,使用数值会报错
print(df.loc['a','two'])
print('-------')
print(df.iloc[1:3]) # iloc可以使用索引进行切片
print('-------')
print(df.loc['a':'c']) # loc只能使用标签进行切片


相关文章
|
13天前
|
数据采集 存储 数据挖掘
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第27天】在数据分析领域,Python的Pandas库因其强大的数据处理能力而备受青睐。本文介绍了Pandas在数据导入、清洗、转换、聚合、时间序列分析和数据合并等方面的高效技巧,帮助数据分析师快速处理复杂数据集,提高工作效率。
40 0
|
3月前
|
数据采集 数据可视化 数据挖掘
数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
在数字化时代,数据分析至关重要,而Python凭借其强大的数据处理能力和丰富的库支持,已成为该领域的首选工具。Python作为基石,提供简洁语法和全面功能,适用于从数据预处理到高级分析的各种任务。Pandas库则像是神兵利器,其DataFrame结构让表格型数据的处理变得简单高效,支持数据的增删改查及复杂变换。配合Matplotlib这一数据可视化的魔法棒,能以直观图表展现数据分析结果。掌握这三大神器,你也能成为数据分析领域的高手!
77 2
|
7天前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
Pandas 和 NumPy 是 Python 中不可或缺的数据处理和分析工具。本文通过实际案例深入剖析了 Pandas 的数据清洗、NumPy 的数组运算、结合两者进行数据分析和特征工程,以及 Pandas 的时间序列处理功能。这些高级技巧能够帮助我们更高效、准确地处理和分析数据,为决策提供支持。
19 2
|
14天前
|
存储 数据挖掘 数据处理
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第26天】Python 是数据分析领域的热门语言,Pandas 库以其高效的数据处理功能成为数据科学家的利器。本文介绍 Pandas 在数据读取、筛选、分组、转换和合并等方面的高效技巧,并通过示例代码展示其实际应用。
29 2
|
5天前
|
并行计算 数据挖掘 大数据
Python数据分析实战:利用Pandas处理大数据集
Python数据分析实战:利用Pandas处理大数据集
|
5天前
|
数据采集 数据可视化 数据挖掘
利用Python进行数据分析:Pandas库实战指南
利用Python进行数据分析:Pandas库实战指南
|
1月前
|
机器学习/深度学习 数据采集 算法
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
【10月更文挑战第5天】随着数据科学和机器学习领域的快速发展,处理大规模数据集的能力变得至关重要。Python凭借其强大的生态系统,尤其是NumPy、Pandas和SciPy等库的支持,在这个领域占据了重要地位。本文将深入探讨这些库如何帮助科学家和工程师高效地进行数据分析,并通过实际案例来展示它们的一些高级应用。
47 0
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
|
1月前
|
数据采集 数据挖掘 API
Python数据分析加速器:深度挖掘Pandas与NumPy的高级功能
在Python数据分析的世界里,Pandas和NumPy无疑是两颗璀璨的明星,它们为数据科学家和工程师提供了强大而灵活的工具集,用于处理、分析和探索数据。今天,我们将一起深入探索这两个库的高级功能,看看它们如何成为数据分析的加速器。
40 1
|
1月前
|
数据采集 数据可视化 数据挖掘
Python 数据分析实战:使用 Pandas 进行数据清洗与可视化
【10月更文挑战第3天】Python 数据分析实战:使用 Pandas 进行数据清洗与可视化
83 0
|
2月前
|
数据采集 数据可视化 数据挖掘
数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
【9月更文挑战第2天】数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
56 5