Python_pandas

pandas

pandas常见的数据类型:

  • 一维:Series
  • 二维:DataFrame
  • 三维:Panel
  • 四维:Panel4D
  • N维:PanelND

常用的一般就是Series和DataFrame

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

运行结果:

0.24.1

Series

创建 Series 数据类型

1.通过列表创建Series对象

array = ['粉条','粉丝','粉带']
# 如果不指定索引, 默认从0开始
s1 = pd.Series(data=array)
print(s1)
# 指定索引
ss1 = pd.Series(data=array,index=['A','B','C'])
print(ss1)

运行结果:
Python_pandas
2.通过numpy的对象Ndarray创建Series对象

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

运行结果:
Python_pandas
3.通过字典创建Series对象

dict = {string.ascii_lowercase[i]:i for i in range(10)}
s3 = pd.Series(dict)
print(s3)

运行结果:
Python_pandas

Series 基本操作

import pandas as pd
import numpy as np

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

1.修改Series索引

s1.index = ['A','B','C']
print(s1)

2.Series纵向拼接

array = ['粉条','粉丝','粉带']
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 运算

Series运算规则:按照对应的索引进行计算,如果索引不同,则填充为Nan

import string
import pandas as pd
import numpy as np

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)    

# +
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.median)

# 求和
print(s1.sum)

# 最大值
print(s1.max)

# 最小值
print(s1.min)

特殊的where方法:
series中的where方法运行结果和numpy中完全不同

import pandas as pd
import numpy as np
import string   

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))

运行结果:

a    NaN
b    NaN
c    NaN
d    NaN
e    4.0
dtype: float64
a    10
b    10
c    10
d    10
e     4
dtype: int64
a     0
b     1
c     2
d     3
e    10
dtype: int64

DataFrame

创建 DataFrame 数据类型

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','transfers'])
print(d1)

2.通过numpy对象创建

n = np.arange(8).reshape(2,4)
d2 = pd.DataFrame(data=n,index=['A','B'],columns=['views','loves','comments','transfers'])
print(d2)

3.通过字典创建

dict = {
      'views':[1,2],
      'loves':[3,4],
       'comments':[5,6],
       'transfers':[7,8]
}

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

日期操作的特例:
二维对象(DataFrame)

import pandas as pd
import numpy as np

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

d = pd.DataFrame(data_arr, index=dates, columns=columns)
print(d)

运行结果:
Python_pandas
一维对象(Series):建立一个以2019年每一天作为索引,值为随机数

import pandas as pd
import numpy as np

# 索引
dates = pd.date_range(start='1/1/2019', end='12/31/2019', freq='D')
# 值
datas = np.random.randn(len(dates))
s = pd.Series(datas, index=dates)
print(s[:5])

运行结果:
Python_pandas

DataFrame 基本操作

import pandas as pd
import numpy as np

n = np.arange(8).reshape(2,4)
d = pd.DataFrame(data=n,index=['A','B'],columns=['views','loves','comments','transfers'])

1.查看基础属性

print(d.shape)      # 获取行数和列数
print(d.dtypes)     # 获取列的数据类型
print(d.ndim)       # 获取数组的维度
print(d.index)      # 行索引
print(d.columns)    # 列索引
print(d.values)     # 获取对象的值,二维ndarray数组

2.数组整体状况的查询

print(d.head(1))    #显示头部的几行,默认5行
print(d.tail(1))    #显示尾部的几行,默认5行

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

print('***************************************')
# 统计信息
print(d.describe())

3.转置操作

print(d.T)

4.按列进行排序(默认是升序,降序:设置ascending=False)

print(d.sort_values(by='views',ascending=False))

5.切片

print(d[:1])

6.查询(列)

# 通过标签查询,获取单列信息
print(d.views)
print(d['views'])

# 通过标签查询,获取多列信息
print(d[['views','loves']])

7.通过类似索引的方式查询(行)

# iloc:通过位置获取行数据
print(d.iloc[0])
print(d.iloc[-1:])
  
# loc:通过标签索引获取行数据
print(d.loc['A'])

8.更改pandas的值

d.loc['A'] = np.nan
print(d)

DataFrame_从文件中读取数据

import pandas as pd

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

df.to_csv('doc/csvFile.csv')
print("csv文件保存成功")

# 2). csv文件的读取
df2 = pd.read_csv('doc/csvFile.csv')
print(df2)

# 3). excel文件的写入
df2.to_excel("/tmp/excelFile.xlsx", sheet_name="省份统计")
print("excel文件保存成功")

分组与聚合操作之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]
     }
)

print(df)

1.根据某一列的key值进行统计分析

grouped = df['count1'].groupby(df['province'])
print(grouped.describe())
print(grouped.median())

Python_pandas

2.根据城市统计分析cpunt1的信息

grouped = df['count1'].groupby(df['city'])
print(grouped.max())

Python_pandas
3.指定多个key值进行分类聚合

grouped = df['count1'].groupby([df['province'], df['city']])
print(grouped)
print(grouped.max())
print(grouped.sum())
print(grouped.count())

Python_pandas
4.通过unstack方法, 实现层次化的索引;

print(grouped.max().unstack())

Python_pandas

案例

1_商品数据分析

需求1:

  1. 从 chipo.csv 文件中读取所有的数据
  2. 获取数据中所有的商品名称
  3. 根据商品的价格进行排序(降序),将价格最高的20件产品信息写入 mostHighPrice.xlsx 文件中

代码:

import pandas as pd
import numpy as np

goodsInfo = pd.read_csv('doc/chipo.csv')    
# print(goodsInfo.info())

print("商品名称显示: \n", goodsInfo['item_name'].head())
# print("商品名称显示: \n", goodsInfo.item_name.head())


# 重新赋值
# 将商品的价格去掉 '$' 后,转为float类型,然后根据商品的价格进行降序排序
goodsInfo.item_price = goodsInfo.item_price.str.strip('$').astype(np.float)
highPriceData = goodsInfo.sort_values('item_price', ascending=False)
highPriceData = highPriceData.head(20)

filename = 'doc/mostHighPrice.xlsx'
highPriceData.to_excel(filename)
print("保存成功.......")

运行结果:
Python_pandas
将价格最高的20件产品信息写入 mostHighPrice.xlsx 文件中:
Python_pandas
需求2:

  1. 统计列[item_name]中每种商品出现的频率,绘制柱状图
  2. 根据列[odrder_id]分组,求出每个订单花费的总金额
  3. 根据每笔订单的总金额和其商品的总数量画出散点图

代码:

import pandas as pd
import numpy as np
from pyecharts import Bar
from pyecharts import EffectScatter

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

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


# 获取订单数量
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()

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

柱状图:
Python_pandas
散点图:
Python_pandas

2_消费金额和小费之间的关联与性别和吸烟与否的关系

需求:
1.分别吸烟顾客与不吸烟顾客的消费金额与小费之间的散点图

代码:

import pandas as pd
from pyecharts import Scatter

filename = 'doc/tips.csv'
data = pd.read_csv(filename)

# 实现吸烟顾客消费金额与小费之间的散点图
smoker = data[data['smoker'] == 'Yes']
x_total_bill = smoker['total_bill']
y_tip = smoker['tip']

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']

scatter = Scatter("不吸烟顾客消费金额与小费之间的散点图")
scatter.add("", x_total_bill, y_tip)
scatter.render()

吸烟顾客消费金额与小费之间的散点图:
Python_pandas
不吸烟顾客消费金额与小费之间的散点图:
Python_pandas
2.女性与男性中吸烟与不吸烟顾客的消费金额与小费之间的散点图关系
代码:

import pandas as pd
from pyecharts import Scatter

filename = 'doc/tips.csv'
data = pd.read_csv(filename)

# 女性中吸烟与不吸烟顾客的消费金额与小费之间的散点图
# 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). 绘制散点图
scatter = Scatter("消费金额与小费之间的散点图")
scatter.add("吸烟女顾客", female_smoker['total_bill'], female_smoker['tip'])
scatter.add("不吸烟女顾客", female_no_smoker['total_bill'], female_no_smoker['tip'])    
scatter.render()

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

# 1). 获取所有不吸烟的用户信息
no_smoker = data[data['smoker'] != 'Yes']
# 2).从所有的吸烟用户中找出性别为男的用户信息
female_no_smoker = no_smoker[no_smoker['sex'] == 'Male']
# 3). 绘制散点图
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