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

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

set_index

专门用来将某一列设置为index的方法

DataFrame.set_index(keys,drop=True,append=False,inplace=False,verify_integrity=False)

  • keys:要设置为索引的列名(如有多个应放在一个列表里)
  • drop:将设置为索引的列删除,默认为True
  • append:是否将新的索引追加到原索引后(即是否保留原索引),默认为False
  • inplace :是否在原DataFrame上修改,默认为False
  • verify_integrity:是否检查索引有无重复,默认为False
df1 = pd.DataFrame({
    'year':[2012,2013,2014,2015],
    'month':[1,4,6,8],
    'sale':[55,44,11,33]
})
print(df1)
# 保留原来的列
print(df1.set_index('month',drop=False))
print(df1.set_index('month',append=True)) # 保留原来的索引列 也就是两个索引
print(df1.set_index(pd.Series(range(4))))
df1.set_index('month',inplace=True)
print(df1)

去重

Pandas去重函数:drop_duplicates()

“去重"通过字面意思不难理解,就是删除重复的数据。在一个数据集中,找出重复的数据删并将其删除,最终只保存一个唯一存在的数据项,这就是数据去重的整个过程。删除重复数据是数据分析中经常会遇到的一个问题。通过数据去重,不仅可以节省内存空间,提高写入性能,还可以提升数据集的精确度,使得数据集不受重复数据的影响。

Panda DataFrame对象提供了一个数据去重的函数 drop_duplicates()

DataFrame. drop_duplicates(subset=None,keep='first', inplace=False,ignore_index=False)

  • subset:表示要进去重的列名,默认为 None。
  • keep:有三个可选参数,分别是 first、last、False,默认为first,表示只保留第一次出现的重复项,删除其余重复项,last表示只保留最后一次出现的重复项,False则表示删除所有重复项
  • inplace:布尔值参数,默认为False表示删除重复项后返回一个副本,若为Ture则表示直接在原数据上删除重复项
df1 = pd.DataFrame({
    'year':[2012,2013,2013,2015,2016,2020,2020],
    'month':[1,4,6,8,4,4,4],
    'sale':[55,44,11,33,4,4,4]
})
print(df1)
print(df1.drop_duplicates()) # 默认情况下,他会给予所有列删除重复的列 也就是删除完全一样的两行
print(df1.drop_duplicates(subset='year')) # 设置如果year中有相同数据,那么就删掉

字符串操作

Python会处理字符串起来会很容易,作为工具包的Pandas同样可以简单快速的处理字符串,几乎把Python内置的字符串方法都给复制过来了,这种方法就是Pandas内置的str方法,通俗来说就可以将series和index对象中包含字符串的部分简单看作单个字符串处理,达到批量简单快速处理的目的

  • lower()将的字符串转换为小写。
  • upper()将的字符串转换为大写。. len()得出字符串的长度。
  • strip()去除字符串两边的空格(包含换行符)。
  • split()用指定的分割符分割字符串。
  • cat(sep=“”)用给定的分隔符连接字符串元素。
  • contains (pattern)如果子字符串包含在元素中,则为每个元素返回一个布尔值 True,否则为False。
  • replace(a,b)将值a替换为值b。
  • count(pattern) 返回每个字符串元素出现的次数
  • startswith(pattern)如果 Series 中的元素以指定的字符串开头,则返回True.
  • endswith(pattern)如果 Series中的元素以指定的字符串结尾,则返回True。
  • findall(pattern)以列表的形式返出现的字符串。
  • find(pattern)返回字符串第一次出现的索引位置。

注意:上述所有字符串函数全部适用于DataFrame对象,同时也可以与Python内置的字符串函数一起使用,这些函数在处理Series/DataFrame对象的时候会自动忽略缺失值数据(NaN)

# lower() 字符串变小写
s = pd.Series(['C','Python','java','\tgo',np.nan,'\tCshape','Android'])
print(s.str.lower())
print('-------------------')
# upper() 字符串变大写
print(s.str.upper())
print('-------------------')
# 求字符串长度
print(s.str.len())
print('-------------------')
# 去除左右两边空格
print(s.str.strip())

s = pd.Series(['C C++','Python iPython','java JavaScript','go',np.nan,'Cshape','Android'])
# 对字符串以给定的符号进行分割
print(s.str.split(' ')) 
print('-------------------')
# 对组间字符串进行拼接,以给定的符号进行拼接
print(s.str.cat(sep='---'))

s = pd.Series(['C C++','Python iPython','java JavaScript','go',np.nan,'Cshape','Android'])
# contains 如果子字符串包含再某元素中,那么为每个元素返回一个布尔值,True,否则False
print(s.str.contains('a'))
print('-------------------')
# replace(a,b) 将值a换为值b
print(s.str.replace('a','AAAA'))

# count用于计算每个字符串元素出现的次数
s = pd.Series(['C','Python','java','\tgo',np.nan,'\tCshape','Android','Python','Java','java','C'])
print(s.str.count(pat='Python'))

# endswith startswith 判断Series元素中以指定的元素结尾/开头,返回True
s = pd.Series(['C C++','Python iPython','java JavaScript','go',np.nan,'Cshape','Android'])
print(s.str.startswith('C'))
print('---------------')
print(s.str.endswith('a'))

pandas数据分析三板斧—map,apply,applymap

在日常的数据处理中,经常会对一个DataFrame进行逐行、逐列和逐元素的操作,对应这些操作,Pandas中的map、apply和applymap可以解决绝大部分这样的数据处理需求

三种方法的使用和区别:

apply:应用在DataFrame的行或列中;

applymap:应用在DataFrame的每个元素中;

map:应用在单独一列(Series)的每个元素中。

apply()方法

前面也说了apply方法是一般性的"拆分-应用-合并”方法。apply()将一个函数作用于DataFrame中的每个行或者列它既可以得到一个经过广播的标量值,也可以得到一个相同大小的结果数组。我们先来看下函数形式:

df.apply(func,axis=0, raw=False,result_type=None,args=(),**kwds)

  • func :函数应用于每一列或每一行
  • axis:
    0或“索引”:将函数应用于每一列。
    1或“列”:将函数应用于每一行。
df = pd.DataFrame([[4,9]]*3,columns=['A','B'])
print(df)
print(df.apply(np.sum))
print('------------')
print(df.apply(np.sum,axis=1))
# 也可以使用lambda函数做简单的运算
print(df.apply(lambda x : x+1))

这样子的匿名函数显然有点不方便,如果函数体太长也不方便阅读,因此我们可以自己封装一个函数

def cal(df,x,y):
    df['C']=(df['A']+df['B'])*x
    df['D']=(df['A']+df['B'])*y
    return df
print(df.apply(cal,x=1,y=2,axis=1))
print('--------------')
print(df.apply(cal,args=(3,8),axis=1))
print('--------------')
print(df.apply(cal,**{'x':3,'y':3},axis=1))

在这里我们先定义了一个cal 函数,它的作用是计算A.B列和的×倍和y倍添加到C,D列中。这里有三种方式可以完成参数的赋值,

第一种方式直接通过关键字参数赋值,指定参数的值;

第二种方式是使用args 关键字参数传入一个包含参数的元组;

第三种方式传入通过**传入包含参数和值的字典

applymap()函数

print(df.applymap(lambda x: '%.2f'%x))
print('---------------------')
print(df[['A']].applymap(lambda x: '%.2f'%x))
# print(df['A'].applymap(lambda x: '%.2f'%x)) # 会报错这样子

需要注意的是这里必须使用df[[‘A’]],表示这是一个DataFrame,而不是一个Series,如果使用df[‘A’]就会报错。同样从行取元素也要将它先转成DataFrame。还需要注意apply方法和applymap的区别:

apply方法操作的是行或列的运算,而不是元素的运算,比如在这里使用格式化操作就会报错;

applymap方法操作的是元素,因此没有诸如axis这样的参数,它只接受函数传入。

map()方法

如果你对applymap方法搞清楚了,那么map方法就很简单,说白了map方法是应用在Series中的,还是举上面的例子:

print(df[['A']].applymap(lambda x: '%.2f'%x))
print('------------')
print(df['A'].map(lambda x: '%.2f'%x))

案例分析

案例一

首先打印出整体数据进行查看分析

chipo = pd.read_csv('17-data/快餐数据.tsv',sep='\t')
print(chipo.head())
print('----------------')
print(chipo.info())
print('----------------')
print(chipo.columns)
print('----------------')

计算被下单最多的

# 计算被下单最多的
c = chipo[['item_name','quantity']].groupby('item_name',as_index=False).sum()
c.sort_values('quantity',ascending=False,inplace=True)
c

计算一下item_name这一列中有多少商品被下单,那么就是计算这一列中有多少不同的数据

# 计算再item_name这一列中有多少商品被下单
chipo['item_name'].nunique()
# 再choice_description中,下单次数最多的商品是失眠
# value_counts函数可以对Series里面的每个值进行计数并且排序
chipo['choice_description'].value_counts()

计算总下单数

# 总下单数?
total_items_orders = chipo['quantity'].sum()
total_items_orders

将某一类型转换为浮点型

# 将item_price转换为浮点数
print(chipo.dtypes)
chipo['item_price'] = chipo['item_price'].str.strip('$').astype(float)

计算总收入,可以先求出每行收入,然后求和

# 在该数据集对应的时期内,收入是多少
chipo['sub_total']=round(chipo['item_price']*chipo['quantity'],2)
chipo['sub_total'].sum()

计算一天中有多少订单

# 在该数据集中,一共多少订单
chipo['order_id'].nunique()

求每一单的平均价格,其实可以变为求每一行的价格,然后求每行价格的和之后再取平均

# 每一单对应的平均总价是多少
chipo[['order_id','sub_total']].groupby(by=['order_id']).sum()['sub_total'].mean()

求多少中不同类型的产品被卖出

# 一共有多少种不同的商品被售出
chipo['item_name'].nunique()

案例二(过滤和排序)

# 2012年欧洲杯决赛阶段16支球队的数据字段名称解释说明
# Team球队.
# Goals进球数
# Shots on target射正次数.
# Shots off target射偏次数
# Shooting Accuracy射门精确度.
# Goals-to-shots 射门的得分比率. 
# Total shots射门次数

导入数据集

euro12 = pd.read_csv('./18-data/Euro2012_stats.csv')

查看数据集基本信息

print(euro12.info())
print(euro12.head())
# 只选取Goals进球数这一列
print(euro12['Goals'])
print(euro12.Goals)
# 求参加欧洲杯的球队个数
print(euro12['Team'].nunique())
print(euro12.shape[0]) `在这里插入代码片`
print(euro12.index)
print(len(euro12))
# 该数据中一共有多少列?
print(len(euro12.columns))
# 将数据集中的列Team,Yellow Cards 和Red Cards单独存为一个名叫discipline的数据中
discipline = euro12[['Team','Yellow Cards','Red Cards']]
print(discipline)
# 对数据discipline按照先Red Cards再Yellow Cards进行排序
discipline.sort_values(['Red Cards','Yellow Cards'],ascending=False)
# 计算每个球队拿到黄牌数的平均值
round(discipline['Yellow Cards'].mean(),2)
# 找到进球数Goals超过6的球队数据
# print(euro12.Goals>6)
euro12[euro12.Goals>6]
# 选取以字母G开头的球队的数据
euro12[euro12.Team.str.startswith('G')]
# 选取前7列`在这里插入代码片`
euro12.iloc[:,0:7]
# 选取除了最后3列外的所有列
euro12.iloc[:,0:-3]
# 找到England Italy和Russia的射正率
euro12.loc[euro12.Team.isin(['England','Italy','Russia']),['Team','Shooting Accuracy']]

案例三(分类)

drinks = pd.read_csv('18-data/drinks.csv')
# 查看相关学习
print(drinks.info())
print(drinks.head())
# 那个大陆消耗的啤酒最多
# 如果想通过列下标去取列,需要借助iloc[行下标切片,列下标切片]这种方式
drinks[['beer_servings','continent']].groupby('continent').sum().sort_values('beer_servings',ascending=False)[0:1]
drinks.groupby('continent').sum().sort_values('beer_servings',ascending=False)[0:1].beer_servings
drinks.groupby('continent').sum().sort_values('beer_servings',ascending=False).head(1)
drinks.groupby('continent').sum().sort_values('beer_servings',ascending=False).iloc[0:1,0:1] # 使用iloc方式
# 打印出每个大陆(continent)的红酒(wine_servings)消耗的描述性统计值
drinks.groupby('continent').wine_servings.describe() # 使用describe方法打印出描述性信息
# 打印出每个大陆每种就类别的消耗平均值
drinks.groupby('continent').mean()
# 打印出每个大陆每种酒类别的消耗中位数
drinks.groupby('continent').median()
# 打印出每个大陆对spirit消耗的平均值,最大值和最小值
drinks.groupby('continent').spirit_servings.agg(['mean','max','min'])
相关文章
|
2月前
|
数据采集 数据可视化 数据挖掘
数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
在数字化时代,数据分析至关重要,而Python凭借其强大的数据处理能力和丰富的库支持,已成为该领域的首选工具。Python作为基石,提供简洁语法和全面功能,适用于从数据预处理到高级分析的各种任务。Pandas库则像是神兵利器,其DataFrame结构让表格型数据的处理变得简单高效,支持数据的增删改查及复杂变换。配合Matplotlib这一数据可视化的魔法棒,能以直观图表展现数据分析结果。掌握这三大神器,你也能成为数据分析领域的高手!
48 2
|
5天前
|
数据挖掘 Python
Pandas数据分析实战(2):2023美国财富1000强公司情况
Pandas数据分析实战(2):2023美国财富1000强公司情况
16 0
|
5天前
|
数据采集 数据挖掘 Python
Pandas数据分析实战(1):2023美国财富1000强公司情况
Pandas数据分析实战(1):2023美国财富1000强公司情况
17 0
|
1月前
|
数据采集 数据可视化 数据挖掘
数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
【9月更文挑战第2天】数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
49 5
|
2月前
|
数据挖掘 大数据 数据处理
数据分析师的秘密武器:精通Pandas DataFrame合并与连接技巧
【8月更文挑战第22天】在数据分析中,Pandas库的DataFrame提供高效的数据合并与连接功能。本文通过实例展示如何按员工ID合并基本信息与薪资信息,并介绍如何基于多列(如员工ID与部门ID)进行更复杂的连接操作。通过调整`merge`函数的`how`参数(如'inner'、'outer'等),可实现不同类型的连接。此外,还介绍了使用`join`方法根据索引快速连接数据,这对于处理大数据集尤其有用。掌握这些技巧能显著提升数据分析的能力。
52 1
|
2月前
|
算法 数据挖掘 数据处理
豆瓣评分8.7!Python pandas创始人亲码的数据分析入门手册!
在众多解释型语言中,Python最大的特点是拥有一个巨大而活跃的科学计算社区。进入21世纪以来,在行业应用和学术研究中采用python进行科学计算的势头越来越猛。 近年来,由于Python有不断改良的库(主要是pandas),使其成为数据处理任务的一大代替方案,结合其在通用编程方面的强大实力,完全可以只使用Python这一种语言去构建以数据为中心的应用程序。 作为一个科学计算平台,Python的成功源于能够轻松的集成C、C++以及Fortran代码。大部分现代计算机环境都利用了一些Fortran和C库来是西安线性代数、优选、积分、快速傅里叶变换以及其他诸如此类的算法。
|
2月前
|
算法 数据挖掘 数据处理
豆瓣评分8.7!Python pandas创始人亲码的数据分析入门手册!
在众多解释型语言中,Python最大的特点是拥有一个巨大而活跃的科学计算社区。进入21世纪以来,在行业应用和学术研究中采用python进行科学计算的势头越来越猛。 近年来,由于Python有不断改良的库(主要是pandas),使其成为数据处理任务的一大代替方案,结合其在通用编程方面的强大实力,完全可以只使用Python这一种语言去构建以数据为中心的应用程序。 作为一个科学计算平台,Python的成功源于能够轻松的集成C、C++以及Fortran代码。大部分现代计算机环境都利用了一些Fortran和C库来是西安线性代数、优选、积分、快速傅里叶变换以及其他诸如此类的算法。
|
2月前
|
数据采集 数据挖掘 数据处理
Python数据分析:Numpy、Pandas高级
在上一篇博文中,我们介绍了Python数据分析中NumPy和Pandas的基础知识。本文将深入探讨NumPy和Pandas的高级功能,并通过一个综合详细的例子展示这些高级功能的应用。
|
2月前
|
数据采集 数据挖掘 数据处理
Python数据分析:Numpy、Pandas基础
本文详细介绍了 Python 中两个重要的数据分析库 NumPy 和 Pandas 的基础知识,并通过一个综合的示例展示了如何使用这些库进行数据处理和分析。希望通过本篇博文,能更好地理解和掌握 NumPy 和 Pandas 的基本用法,为后续的数据分析工作打下坚实的基础。
下一篇
无影云桌面