python--pandas模块

pandas简介

pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

常见的数据类型

  • Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近。Series如今能保存不同种数据类型,字符串、boolean值、数字等都能保存在Series中。
  • Time- Series:以时间为索引的Series。
  • DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。
  • Panel :三维的数组,可以理解为DataFrame的容器。

pandas创建Series数据类型

import pandas as pd
import numpy as np
import  string


# 查看pandas版本信息
print(pd.__version__)

# ********************创建Series对象

#  1). 通过列表创建Series对象
array = ["粉条", "粉丝", "粉带"]
# 如果不指定索引, 默认从0开始;
s1 = pd.Series(data=array)
print(s1)
# 如果不指定索引, 默认从0开始;
ss1 = pd.Series(data=array, index=['A', 'B', 'C'])
print(ss1)

# 2). 通过numpy的对象Ndarray创建Series;
n = np.random.randn(5)   # 随机创建一个ndarray对象;
s2 = pd.Series(data=n)
print(s2)
# 修改元素的数据类型;
ss2 = s2.astype(np.int)
print(ss2)

# 3). 通过字典创建Series对象;
dict = {string.ascii_lowercase[i]:i for i in range(10)}
s3 = pd.Series(dict)
print(s3)

Series基本操作

import pandas as pd
import numpy as np
import  string




array = ["粉条", "粉丝", "粉带"]
s1 = pd.Series(data=array)
print(s1)


# 1). 修改Series索引
print(s1.index)
s1.index = ['A', 'B', 'C']
print(s1)


# 2). Series纵向拼接;
array = ["粉条", "粉丝", "粉带"]
# 如果不指定索引, 默认从0开始;
s2 = pd.Series(data=array)
s3 = s1.append(s2)
print(s3)

# 3). 删除指定索引对应的元素;
s3 = s3.drop('C')  # 删除索引为‘C’对应的值;
print(s3)


# 4). 根据指定的索引查找元素
print(s3['B'])
s3['B'] = np.nan
print(s3)


# 5). 切片操作  --- 同列表
print(s3[:2])
print(s3[::-1])
print(s3[-2:])  # 显示最后两个元素

Series运算

import pandas as pd
import numpy as np
import  string

s1  = pd.Series(np.arange(5), index=list(string.ascii_lowercase[:5]))
s2  = pd.Series(np.arange(2, 8), index=list(string.ascii_lowercase[2:8]))

print(s1)
print(s2)

# *****************8按照对应的索引进行计算, 如果索引不同,则填充为Nan;


# 加法
print(s1 + s2)
print(s1.add(s2))


# -
print(s1 - s2)
print(s1.sub(s2))


# *
print(s1 * s2)
print(s1.mul(s2))


# /
print(s1 / s2)
print(s1.div(s2))



# 求中位数
print(s1)
print(s1.median())

# 求和
print(s1.sum())
# max
print(s1.max())

# min
print(s1.min())

特殊的where方法

import pandas as pd
import numpy as np
import string

# &**********series中的where方法运行结果和numpy中完全不同;
s1 = pd.Series(np.arange(5), index=list(string.ascii_lowercase[:5]))
print(s1.where(s1 > 3))

# 对象中不大于3的元素赋值为10;
print(s1.where(s1 > 3, 10))

# 对象中大于3的元素赋值为10;
print(s1.mask(s1 > 3, 10))

python--pandas模块

创建DataFrame数据类型

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

# 方法1: 通过列表创建
li = [
    [1, 2, 3, 4],
    [2, 3, 4, 5]
]

# DataFRame对象里面包含两个索引, 行索引(0轴, axis=0), 列索引(1轴, axis=1)
d1 = pd.DataFrame(data=li, index=['A', 'B'], columns=['views', 'loves', 'comments', 'tranfers'])
# print(d1)

# 方法2: 通过numpy对象创建
narr = np.arange(8).reshape(2, 4)
# DataFRame对象里面包含两个索引, 行索引(0轴, axis=0), 列索引(1轴, axis=1)
d2 = pd.DataFrame(data=narr, index=['A', 'B'], columns=['views', 'loves', 'comments', 'tranfers'])
# print(d2)

# 方法三: 通过字典的方式创建;
dict = {
    'views': [1, 2, ],
    'loves': [2, 3, ],
    'comments': [3, 4, ]

}
d3 = pd.DataFrame(data=dict, index=['粉条', "粉丝"])
print(d3)


# 日期操作的特例:
pd.date_range()
dates = pd.date_range(start='1/1/2018', end='1/08/2018')
print(dates)


# 行索引
dates = pd.date_range(start='today', periods=6)
# 数据
data_arr = np.random.randn(6, 4)
# 列索引
columns = ['A', 'B', 'C', 'D']
d4 = pd.DataFrame(data_arr, index=dates, columns=columns)
print(d4)



# 一维对象: 建立一个以2019年每一天作为索引, 值为随机数;
dates = pd.date_range(start='1/1/2019', end='12/31/2019', freq='D')
datas = np.random.randn(len(dates))
s1 = pd.Series(datas, index=dates)
print(s1[:3])

DataFrame的基本操作

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt


narr = np.arange(8).reshape(2, 4)
# DataFRame对象里面包含两个索引, 行索引(0轴, axis=0), 列索引(1轴, axis=1)
d2 = pd.DataFrame(data=narr, index=['A', 'B'], columns=['views', 'loves', 'comments', 'tranfers'])
print(d2)



# **********************1). 查看基础属性***********************
print(d2.shape)  # 获取行数和列数;
print(d2.dtypes)  # 列数据类型
print(d2.ndim)  # 获取数据的维度
print(d2.index) # 行索引
print(d2.columns) # 列索引
print(d2.values, type(d2.values))   # 对象的值, 二维ndarray数组;



# ******************************2). 数据整体状况的查询*************
print(d2.head(1))  # 显示头部的几行, 默认5行
print(d2.tail(1))  # 显示头部的尾行, 默认5行

print("*"*10)
# 相关信息的预览: 行数, 列数, 列类型, 内存占用
print("info:", d2.info())

print("统计".center(50, '*'))
# 快速综合用计结果: 计数, 均值, 标准差, 最小值, 1/4位数, 中位数, 3/4位数, 最大值;
print(d2.describe())


# 3). 转置操作
print(d2.T)

# 4). 按列进行排序
print(d2)
# 按照指定列进行排序, 默认是升序, 如果需要降序显示,设置ascending=False;
print(d2.sort_values(by="views", ascending=False))


# 5). 切片及查询
print(d2[:1])   # 可以实现切片, 但是不能索引;
print('1:\n', d2['views'])   # 通过标签查询, 获取单列信息
print('2:\n', d2.views)   # 和上面是等价的;
print(d2[['views', 'comments']])  # 通过标签查询多列信息



# 6). 通过类似索引的方式查询;
#       - iloc(通过位置进行行数据的获取),
#        - loc(t通过标签索引行数据)
# print(d2[0])
print(d2)
print(d2.iloc[0])
print(d2.iloc[-1:])


# print(d2['A'])    # 报错
print(d2)
print(d2.loc['A'])



# 7). 更改pandas的值;
d2.loc['A'] = np.nan
print(d2)

# print(d2.info())

python--pandas模块
python--pandas模块

分组与聚合操作之groupby

pandas提供了一个灵活高效的groupby功能,
1). 它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。
2). 根据一个或多个键(可以是函数、数组或DataFrame列>名)拆分pandas对象。
3). 计算分组摘要统计,如计数、平均值、标准差,或用户自定义函数。

import pandas as pd


df = pd.DataFrame(
    {'province': ['陕西', '陕西', '四川', '四川', '陕西'],
     'city': ['咸阳', '宝鸡', '成都', '成都', '宝鸡'],
     'count1': [1, 2, 3, 4, 5],
     'count2': [1, 2, 33, 4, 5]
     }
)



# 陕西      咸阳    1
#          宝鸡     1

print(df)
# 根据某一列的key值进行统计分析;
grouped = df['count1'].groupby(df['province'])
print(grouped.describe())
print(grouped.median())

# 根据城市统计分析cpunt1的信息;
grouped = df['count1'].groupby(df['city'])
print(grouped.max())


# 指定多个key值进行分类聚合;
grouped = df['count1'].groupby([df['province'], df['city']])
print(grouped)
print(grouped.max())
print(grouped.sum())
print(grouped.count())

#  通过unstack方法, 实现层次化的索引;
# print(grouped.max().unstack())

字符串操作

import pandas as pd
import numpy as np


series1= pd.Series(['$A:1', '$B:2', '$C:3', np.nan, '$cat:3'])
print(series1)

# 将所有的字母转换为小写字母, 除了缺失值
print(series1.str.lower())


# 将所有的字母转换为大写字母, 除了缺失值
print(series1.str.upper())

# 分离
print(series1.str.split(":"))

# 去掉左右两端的某个字符
print(series1.str.strip('$'))

案例–商品数据分析

文件名称: doc/chipo.csv
文件描述: 每列数据分别代表如下: 订单编号, 订单数量, 商品名称, 商品详细选择项, 商品总价格
需求1:
1). 从文件中读取所有的数据;
2). 获取数据中所有的商品名称;
3). 跟据商品的价格进行排序, 降序,
将价格最高的20件产品信息写入mosthighPrice.xlsx文件中;

需求2:
1). 统计列[item_name]中每种商品出现的频率,绘制柱状图
(购买次数最多的商品排名-绘制前5条记录)
2). 根据列 [odrder_id] 分组,求出每个订单花费的总金额。
3). 根据每笔订单的总金额和其商品的总数量画出散点图。

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

#
# # 需求1:
# #     1). 从文件中读取所有的数据;
# #     2). 获取数据中所有的商品名称;
goodsInfo = pd.read_csv('doc/chipo.csv')
# print(goodsInfo.head())
# print(goodsInfo.tail())
print(goodsInfo.info())
# print(goodsInfo.describe())
print("商品名称显示: \n", goodsInfo['item_name'].head())
print("商品名称显示: \n", goodsInfo.item_name.head())

#
# #
# # 需求1:
# #
# #     3). 跟据商品的价格进行排序, 降序,
# #     将价格最高的20件产品信息写入mosthighPrice.xlsx文件中;
# # 重新赋值;
goodsInfo.item_price = goodsInfo.item_price.str.strip('$').astype(np.float)
highPriceData = goodsInfo.sort_values('item_price', ascending=False)
print(highPriceData.head(5))
filename = '/tmp/mostHighPrice.xlsx'
highPriceData.to_excel(filename)
print("保存成功.......")

# # 需求2:
# #     1). 统计列[item_name]中每种商品出现的频率,绘制柱状图
# #             (购买次数最多的商品排名-绘制前5条记录)
goodsInfo = pd.read_csv('doc/chipo.csv')
# new_info会统计每个商品名出现的次数;其中 Unnamed: 0就是我们需要获取的商品出现频率;
newInfo = goodsInfo.groupby('item_name').count()
mostRaiseGoods = newInfo.sort_values('Unnamed: 0', ascending=False)['Unnamed: 0'].head(5)
# print(mostRaiseGoods, type(mostRaiseGoods))   # series对象;

# 获取对象中的商品名称;
x = mostRaiseGoods.index
# 获取商品出现的次数;
y = mostRaiseGoods.values

from  pyecharts import  Bar

bar = Bar("购买次数最多的商品排名")
bar.add("", x, y)
bar.render()









# 需求2:
#     2). 根据列 [odrder_id] 分组,求出每个订单花费的总金额======订单数量(quantity), 订单总价(item_price)。
#     3). 根据每笔订单的总金额和其商品的总数量画出散点图。


goodsInfo = pd.read_csv('doc/chipo.csv')
# 获取订单数量
quantity = goodsInfo.quantity
# 获取订单总价
item_price = goodsInfo.item_price \
    = goodsInfo.item_price.str.strip('$').astype(np.float)

# 根据列 [odrder_id] 分组
order_group = goodsInfo.groupby("order_id")
# 每笔订单的总金额
x = order_group.item_price.sum()
# 商品的总数量
y = order_group.quantity.sum()


from pyecharts import  EffectScatter
scatter = EffectScatter("每笔订单的总金额和其商品的总数量关系散点图")
scatter.add("", x, y)
scatter.render()

python--pandas模块
python--pandas模块

python--pandas模块

案例–消费金额和小费之间的关联与性别和吸烟与否的关系

文件名称: doc/tips.csv
文件内容: 总消费金额, 小费金额, 性别, 是否抽烟, 日期, 时间, 星期
需求:
- 分别吸烟顾客与不吸烟顾客的消费金额与小费之间的散点图;
- 女性与男性中吸烟与不吸烟顾客的消费金额与小费之间的散点图关系;
“”"

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt


filename = 'doc/tips.csv'
data = pd.read_csv(filename)
# print(data.head())
# print(data.info())


# # 实现吸烟顾客消费金额与小费之间的散点图
# smoker = data[data['smoker'] == 'Yes']
# # print(smoker.head())
# x_total_bill = smoker['total_bill']
# y_tip = smoker['tip']
#
# from pyecharts import  Scatter
# scatter = Scatter("吸烟顾客消费金额与小费之间的散点图")
# scatter.add("", x_total_bill, y_tip)
# scatter.render()



# # 实现不吸烟顾客消费金额与小费之间的散点图
# no_smoker = data[data['smoker'] != 'Yes']
# # print(smoker.head())
# x_total_bill = no_smoker['total_bill']
# y_tip = no_smoker['tip']
#
# from pyecharts import  Scatter
# scatter = Scatter("不吸烟顾客消费金额与小费之间的散点图")
# scatter.add("", x_total_bill, y_tip)
# scatter.render()



# 女性中吸烟与不吸烟顾客的消费金额与小费之间的散点图关系;
# 1). 获取所有吸烟的用户信息
smoker = data[data['smoker'] == 'Yes']
# 2).从所有的吸烟用户中找出性别为女的用户信息;
female_smoker = smoker[smoker['sex']=='Female']


# 1). 获取所有不吸烟的用户信息
no_smoker = data[data['smoker'] != 'Yes']
# 2).从所有的吸烟用户中找出性别为女的用户信息;
female_no_smoker = no_smoker[no_smoker['sex']=='Female']
# 3). 绘制散点图
from pyecharts import  Scatter
scatter = Scatter("消费金额与小费之间的散点图")
scatter.add("吸烟女顾客", female_smoker['total_bill'], female_smoker['tip'])
scatter.add("不吸烟女顾客", female_no_smoker['total_bill'], female_no_smoker['tip'])

scatter.render()

python--pandas模块
python--pandas模块
python--pandas模块