数据分析从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'])
相关文章
|
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