数据分析——Pandas(基础)

编程工具:jupyter notebook 

一、基本认识

1. 导入库

import pandas as pd
import warnings

2. 屏蔽警告提示

warnings.filterwarnings('ignore')

 3.读取Excel

df = pd.read_excel('./data/demo_01.xlsx', engine='openpyxl')       # 相对路径,engine='openpyxl'  引擎可以不加,但是旧版本需要加
df = pd.read_excel('./data/demo_01.xlsx') 

4.预览前5行

df.head(5)

 5.列名对齐

  • display.unicode.ambiguous_as_wide
  • display.unicode.east_asian_width
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)

 6.禁止换行

pd.set_option('expand_frame_repr', False)

7.显示所有行

pd.set_option('display.max_rows', None)

8.最多显示10行

pd.set_option('display.max_rows', 10)

9.显示所有列

pd.set_option('display.max_columns', None)

10.最多显示10列

pd.set_option('display.max_columns', 10)

11.设置内容的显示宽度

pd.set_option('display.width', 100)

12.设置数值的显示精度

pd.set_option('display.precision', 2)

13.设置小数的显示格式

pd.set_option('display.float_format', lambda x: '%.2f' % x)
# '{:.2f}'.format(x),小数点
# '{:.2%}'.format(x),百分比

14.设置计算引擎

pd.set_option('compute.use_numba', True)      # 当数据处理量较大速度较慢时可以设置为此计算引擎

15.获取指定选项的设置情况

pd.get_option('compute.use_numba')

16.条件格式

# pandas.io.formats.style.Styler
df.style.highlight_max()   #高亮显示最大值

二、Scries对象

import pandas as pd

1.创建Series对象

pd.Series([80,90,88])      #pd.Series(data=None,index=None,dtype=None,name=None,copy=False,fastpath=False,)

 2.设置Series索引

2.1 数字索引

pd.Series(data=[80,90,88],index=[1,2,3])

 2.2字符串索引

pd.Series(data=[80,90,88],index=['张三','李四','王五'])

 3.Series的索引操作

s4 = pd.Series(data=[80,90,88,96],index=['张三','李四','王五','赵六'])
s4

# 取第一个同学的成绩
s4[0],s4['张三']

 3.1通过索引号获取值

s4[0]

80

3.2通过索引名获取值

s4['张三']

80

3.3通过多个索引名获取值

s4[ ['张三','赵六'] ]
张三    80
赵六    96
dtype: int64

3.4通过索引名切片获取值
 

s4
张三    80
李四    90
王五    88
赵六    96
dtype: int64
s4['张三':'王五']       # 通过索引名切片,左右都包含;通过索引号切片左闭右开
张三    80
李四    90
王五    88
dtype: int64

3.5通过索引号切片获取值

s4[:3]          #通过索引号切片左闭右开
张三    80
李四    90
王五    88
dtype: int64

3.6获取Series的索引

s4.index    # 获取s4的索引
Index(['张三', '李四', '王五', '赵六'], dtype='object')

3.7获取Series的值

s4.values     # 获取s4的值
array([80, 90, 88, 96], dtype=int64)
type(s4.values)
numpy.ndarray

3.8判断Series是否包含空值

s4.hasnans
False

三、DataFrame对象

import pandas as pd

1.创建DataFrame对象

data = [[110, 105, 99],
        [105, 88, 115],
        [109, 120, 130]]
index = [0, 1, 2]
columns = ['语文', '数学', '英语']

#pd.DataFrame(data=None,index:'Optional[Axes]'=None,columns:'Optional[Axes]'=None,dtype:'Optional[Dtype]'= None,copy:'bool'=False)
df = pd.DataFrame(data=data,index=index,columns=columns)     
df

 2.遍历DataFrame每列

df['语文']
0    110
1    105
2    109
Name: 语文, dtype: int64
type(df['语文'])
pandas.core.series.Series
for col in df.columns:
    print(type(df[col]))
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>

3.通过字典创建DataFrame

  • value为多个元素
dct = {
    '语文': [110, 105, 99],
    '数学': [105, 88, 115],
    '英语': [109, 120, 130]}

df = pd.DataFrame(data=dct,index=[1,2,3])
df

 

 4.通过字典创建DataFrame

  • value为一个元素
dct = {
    '语文': 110,
    '数学': 105,
    '英语': 109}

df = pd.DataFrame(data=dct,index=[0])      # 一行数据 index 也要传入列表格式
df

 

dct = {'语文': [110],
    '数学': [105],
    '英语': [109]}
pd.DataFrame(data=dct)

 

 5.DataFrame的重要属性

5.1查看所有元素的值

dct = {
    '语文': [110, 105, 99],
    '数学': [105, 88, 115],
    '英语': [109, 120, 130]}
df = pd.DataFrame(data=dct,index=[1,2,3])
df

df.values
array([[110, 105, 109],
       [105,  88, 120],
       [ 99, 115, 130]], dtype=int64)

5.2查看某列的唯一值

df['语文'].unique()    # 查看 语文 列中去重后的数据
array([110, 105,  99], dtype=int64)

5.3查看所有元素的类型

df.dtypes    # 查看每个字段的数据类型
语文    int64
数学    int64
英语    int64
dtype: object

5.4查看所有行名

# index ——> 行索引,索引
# column ——> 列索引,字段,列名
df.index
Int64Index([1, 2, 3], dtype='int64')

5.5重命名行名

df.index = ['a1','a2','a3']
df

 5.6查看所有列名

df.columns
Index(['语文', '数学', '英语'], dtype='object')

5.7重命名列名

df.columns = ['语','数','外']
df

 5.8行列转置

df.T

 5.9查看前n条数据

  • 默认5条
df.head()

 

 5.10查看前10条数据

df.head(10)

 5.11查看后n条数据

  • 默认5条
df.tail()

 5.12查看后10条数据

df.tail(10)

 5.13查看行数

  • 0表示行
df.shape[0]

3

5.14查看列数

  • 1表示列
df.shape[1]

3

5.15查看基本信息

  • 索引、数据类型、非空值数量和内存信息
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 3 entries, a1 to a3
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   语       3 non-null      int64
 1   数       3 non-null      int64
 2   外       3 non-null      int64
dtypes: int64(3)
memory usage: 204.0+ bytes

6.DataFrame的重要函数

6.1查看每列的描述统计信息

  • 返回DataFrame类型
df.describe()

 

type(df.describe())
pandas.core.frame.DataFrame
df.describe().round(2)  # 保留两位小数

 6.2返回每列非空值数量

df.count()
语    3
数    3
外    3
dtype: int64

6.3返回每列的合计

  • 无法计算返回空值
df.sum()
语    314
数    308
外    359
dtype: int64

6.4返回每列的最大值

df.max()
语    110
数    115
外    130
dtype: int64

6.5返回每列的最小值

df.min()
语     99
数     88
外    109
dtype: int64

6.6返回最大值的索引号

  • 原始的数字索引
df

# 原始索引:从0开始递增
df['语'].argmax()    # 语文中最大的原始索引

0

6.7返回最小值的索引号

  • 原始的数字索引
df['语'].argmin()

 2

6.8 返回最大值的索引名

  • 自定义的索引
df['语'].idxmax()
'a1'

6.9返回最小值的索引名

  • 自定义的索引
df['语'].idxmin()
'a3'

6.10返回每列的平均值

df.mean()
语    104.666667
数    102.666667
外    119.666667
dtype: float64

6.11返回每列的中位数

  • 中位数又称中值,按顺序排列后处于中间位置的数值
df.median()
语    105.0
数    105.0
外    120.0
dtype: float64

6.12返回每列的方差

  • 用于衡量一组数据的离散程度
df.var()
语     30.333333
数    186.333333
外    110.333333
dtype: float64

6.13返回每列的标准差

  • 标准差是方差的算术平方根
  • 也用于衡量一组数据的离散程度
df.std()
语     5.507571
数    13.650397
外    10.503968
dtype: float64

6.14检查df中的空值

  • 空值为True,否则为False,返回布尔型数组
df.isnull()

 

 6.15检查df中的非空值

  • 非空值为True,否则为False,返回布尔型数组
df.notnull()

 

四、数据导入

import pandas as pd

1.导入Excel

df1 = pd.read_excel('./data/demo_04.xlsx')    # 默认读取第一个工作表
df1.head(5)

2.导入Excel的指定Sheet

pd.read_excel('./data/demo_04.xlsx', sheet_name='工作表2')      # 参数 sheet_name 设为想要读取的工作表名称

 

 3.设置第2行为列索引

pd.read_excel('./data/demo_04.xlsx', sheet_name='工作表3')   # 默认第一行作为表头

pd.read_excel('./data/demo_04.xlsx', sheet_name='工作表3',header=1)

 

4.通过指定的列索引来导入第1列

pd.read_excel('./data/demo_04.xlsx', sheet_name='工作表1',usecols=[0])

 

 5.通过指定的列索引来导入第1列、第4列

pd.read_excel('./data/demo_04.xlsx', sheet_name='工作表1',usecols=[0,3])

 6.通过指定的列名来导入指定列

pd.read_excel('./data/demo_04.xlsx', sheet_name='工作表1',usecols=['name','sex'])

 7.导入csv,并指定编码格式

pd.read_csv('./data/demo_04.csv',encoding='utf-8')

 8.导入txt,并指定编码格式

pd.read_csv('./data/demo_04.txt',encoding='utf-8',sep='\t')    # 参数 sep 设置分隔符,默认是逗号

 9.导入json,并指定数据结构 

  • split, records, index, table, values

 (1)index结构

# {
#   "0": {
#     "姓名": "王晨",
#     "电话": 13807990096
#   },
#   "1": {
#     "姓名": "刘英",
#     "电话": 15317068630
#   },
#   "2": {
#     "姓名": "王婷",
#     "电话": 15069162098
#   },
#   "3": {
#     "姓名": "余颖",
#     "电话": 15110247460
#   },
#   "4": {
#     "姓名": "程秀珍",
#     "电话": 15052126982
#   },
#   "5": {
#     "姓名": "孙飞",
#     "电话": 15187633436
#   },
#   "6": {
#     "姓名": "戚阳",
#     "电话": 15749935938
#   },
#   "7": {
#     "姓名": "李璐",
#     "电话": 18712343795
#   },
#   "8": {
#     "姓名": "秦静",
#     "电话": 15800229061
#   },
#   "9": {
#     "姓名": "张莹",
#     "电话": 13718317243
#   }
# }
pd.read_json('./data/index.json',orient='index')       # 通过 orient 参数修改 json 的数据结构格式

 

 (2)records结构

# [
#   {
#     "姓名": "王晨",
#     "电话": 13807990096
#   },
#   {
#     "姓名": "刘英",
#     "电话": 15317068630
#   },
#   {
#     "姓名": "王婷",
#     "电话": 15069162098
#   },
#   {
#     "姓名": "余颖",
#     "电话": 15110247460
#   },
#   {
#     "姓名": "程秀珍",
#     "电话": 15052126982
#   },
#   {
#     "姓名": "孙飞",
#     "电话": 15187633436
#   },
#   {
#     "姓名": "戚阳",
#     "电话": 15749935938
#   },
#   {
#     "姓名": "李璐",
#     "电话": 18712343795
#   },
#   {
#     "姓名": "秦静",
#     "电话": 15800229061
#   },
#   {
#     "姓名": "张莹",
#     "电话": 13718317243
#   }
# ]
pd.read_json('./data/records.json',orient='records')

 (3)split结构

# {
#   "columns": [
#     "姓名",
#     "电话"
#   ],
#   "index": [
#     0,
#     1,
#     2,
#     3,
#     4,
#     5,
#     6,
#     7,
#     8,
#     9
#   ],
#   "data": [
#     [
#       "王晨",
#       13807990096
#     ],
#     [
#       "刘英",
#       15317068630
#     ],
#     [
#       "王婷",
#       15069162098
#     ],
#     [
#       "余颖",
#       15110247460
#     ],
#     [
#       "程秀珍",
#       15052126982
#     ],
#     [
#       "孙飞",
#       15187633436
#     ],
#     [
#       "戚阳",
#       15749935938
#     ],
#     [
#       "李璐",
#       18712343795
#     ],
#     [
#       "秦静",
#       15800229061
#     ],
#     [
#       "张莹",
#       13718317243
#     ]
#   ]
# }
pd.read_json('./data/split.json',orient='split')

 (4)table结构

# {
#   "schema": {
#     "fields": [
#       {
#         "name": "index",
#         "type": "integer"
#       },
#       {
#         "name": "姓名",
#         "type": "string"
#       },
#       {
#         "name": "电话",
#         "type": "integer"
#       }
#     ],
#     "primaryKey": [
#       "index"
#     ],
#     "pandas_version": "0.20.0"
#   },
#   "data": [
#     {
#       "index": 0,
#       "姓名": "王晨",
#       "电话": 13807990096
#     },
#     {
#       "index": 1,
#       "姓名": "刘英",
#       "电话": 15317068630
#     },
#     {
#       "index": 2,
#       "姓名": "王婷",
#       "电话": 15069162098
#     },
#     {
#       "index": 3,
#       "姓名": "余颖",
#       "电话": 15110247460
#     },
#     {
#       "index": 4,
#       "姓名": "程秀珍",
#       "电话": 15052126982
#     },
#     {
#       "index": 5,
#       "姓名": "孙飞",
#       "电话": 15187633436
#     },
#     {
#       "index": 6,
#       "姓名": "戚阳",
#       "电话": 15749935938
#     },
#     {
#       "index": 7,
#       "姓名": "李璐",
#       "电话": 18712343795
#     },
#     {
#       "index": 8,
#       "姓名": "秦静",
#       "电话": 15800229061
#     },
#     {
#       "index": 9,
#       "姓名": "张莹",
#       "电话": 13718317243
#     }
#   ]
# }
pd.read_json('./data/table.json',orient='table')

 (5)values结构

# [
#   [
#     "王晨",
#     13807990096
#   ],
#   [
#     "刘英",
#     15317068630
#   ],
#   [
#     "王婷",
#     15069162098
#   ],
#   [
#     "余颖",
#     15110247460
#   ],
#   [
#     "程秀珍",
#     15052126982
#   ],
#   [
#     "孙飞",
#     15187633436
#   ],
#   [
#     "戚阳",
#     15749935938
#   ],
#   [
#     "李璐",
#     18712343795
#   ],
#   [
#     "秦静",
#     15800229061
#   ],
#   [
#     "张莹",
#     13718317243
#   ]
# ]
df = pd.read_json('./data/values.json',orient='values')
df.columns = ['姓名','电话']    # values 需要自己定义字段名称
df

五、数据抽取

import pandas as pd

1.创建DataFrame对象

data = [[109, 107, 100],
        [105, 114, 135],
        [98, 88, 120],
        [145, 150, 130]]
name = ['刘备', '关羽', '张飞', '诸葛亮']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(
    data=data,
    index=name,
    columns=columns)
df

 2.使用loc方法抽取

# 通过名称筛选
df.loc['刘备']
语文    109
数学    107
英语    100
Name: 刘备, dtype: int64
type(df.loc['刘备'])

pandas.core.series.Series

3.使用iloc方法抽取

# 通过索引号筛选
df.iloc[0]
语文    109
数学    107
英语    100
Name: 刘备, dtype: int64
df.iloc[[0,3]]    # 读取下表为 0 ,3 的行

 4.抽取指定行的数据

  • 使用loc和iloc

4.1从“刘备”到“诸葛亮”

df.loc['刘备':'诸葛亮']    # 通过切片方式,左闭右闭

 4.2第1行到“关羽”

df.loc[:'关羽']

 4.3第1行到第4行

df.iloc[:4]

 4.4第2行到最后1行

df.iloc[1:]

 5.抽取指定列的数据

df

 5.1直接使用列名

df['语文']
刘备     109
关羽     105
张飞      98
诸葛亮    145
Name: 语文, dtype: int64
df[['语文']]

df[['语文','数学']]

 5.2使用loc和iloc

5.2.1抽取“语文”和“数学”

df.loc[:,['语文','数学']]

 5.2.2抽取第1列和第2列

df.iloc[:,[0,1]]

 5.2.3抽取从“语文”开始到最后1列

df.loc[:,'语文':]

 5.2.4抽取从第1列开始到第3列

df.iloc[:,:3]

 6.抽取指定行列的数据

  • 使用loc和iloc

6.1  “英语”成绩 

df.loc[:,'英语']
刘备     100
关羽     135
张飞     120
诸葛亮    130
Name: 英语, dtype: int64

6.2“关羽”的“英语”成绩

df.loc['关羽','英语']

135

df.loc[['关羽'],['英语']]

 6.3“关羽”的“数学”和“英语”成绩

df.loc[['关羽'],['英语','数学']]

 6.4第2行第3列

df.iloc[1,2]

135

df.iloc[[1],[2]]

 6.5第2行到最后1行,第3列

df.iloc[1:,[2]]

 6.6第2行到最后1行,第1列和第3列

df.iloc[1:,[0,2]]

 6.7所有行,第3列

df.iloc[:,[2]]

 7.按指定条件抽取数据

df

 7.1  语文大于105且数学大于88

df.loc[ (df['语文'] > 105) & (df['数学'] > 88) ]    # 注意加括号

cod1 = df['语文'] > 105
cod2 = df['数学'] > 88
df.loc[ cod1 & cod2]

 7.2  语文大于105或数学大于88

df.loc[ (df['语文'] > 105) | (df['数学'] > 88) ]    # 注意加括号

cod1 = df['语文'] > 105
cod2 = df['数学'] > 88
df.loc[ cod1 | cod2]

 7.3  语文不等于105

  • !=
df.loc[ df['语文'] != 105 ]

 

 7.4  语文不等于105

  • ~
df.loc[~(df['语文'] == 105)]     # 注意括号

 

六、数据新增修改删除

import pandas as pd

1. 创建DataFrame对象

data = [[109, 107, 100],
        [105, 114, 135],
        [98, 88, 120],
        [145, 150, 130]]
name = ['刘备', '关羽', '张飞', '诸葛亮']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(
    data=data,
    index=name,
    columns=columns)
df

 2 .新增数据

2.1  按列新增数据

2.1.1  直接赋值

  • 在最后插入“物理”一列
df['物理'] = [88,77,66,55]
df

 

 2.1.2  loc方法

  • 在最后插入“物理”一列
df.loc[:,'物理'] = [99,89,79,69]
df

 2.1.3  insert方法

  • 在第1列后面插入“物理”列名
del df['物理']    # 删除 ‘物理’ 列
df

 

df.insert(1,'物理',[89,79,69,66])
df

2.2  按行新增数据

2.2.1  新增一行数据

df.loc['赵云'] = [100,70,120,110]
df

 

 2.2.2  新增多行数据

df2 = pd.DataFrame(
    {'语文': [100, 123, 138],
     '数学': [120, 142, 60],
     '英语': [99, 139, 99],
     '物理': [105, 110, 96]},
    index=['马超', '黄忠', '姜维'])
df2

df3 = df.append(df2)    # 必须重新赋值
df,df3
(      语文  物理   数学   英语
 刘备   109  89  107  100
 关羽   105  79  114  135
 张飞    98  69   88  120
 诸葛亮  145  66  150  130
 赵云   100  70  120  110,
       语文   物理   数学   英语
 刘备   109   89  107  100
 关羽   105   79  114  135
 张飞    98   69   88  120
 诸葛亮  145   66  150  130
 赵云   100   70  120  110
 马超   100  105  120   99
 黄忠   123  110  142  139
 姜维   138   96   60   99)

3.修改行列索引

3.1  修改列索引

3.1.1  通过属性赋值

columns = df.columns      # 备份列索引
df.columns = ['语文(上)','物理','数学','英语']
df

df.columns = columns        # 还原
df

3.1.2  通过rename方法

dct = {'语文':'语文(上)','物理':'物理(上)'}     # 定义字典,键为修改前的字段名称,值为修改后的字段名称
df4 = df.rename(dct,axis=1)         # 不会修改原始数据,需要重新赋值
df,df4
(      语文  物理   数学   英语
 刘备   109  89  107  100
 关羽   105  79  114  135
 张飞    98  69   88  120
 诸葛亮  145  66  150  130
 赵云   100  70  120  110,
      语文(上)  物理(上)   数学   英语
 刘备     109     89  107  100
 关羽     105     79  114  135
 张飞      98     69   88  120
 诸葛亮    145     66  150  130
 赵云     100     70  120  110)

3.2 修改行索引

3.2.1  通过属性赋值

#备份行索引
index = df.index
index
Index(['刘备', '关羽', '张飞', '诸葛亮', '赵云'], dtype='object')
df.index = [1,2,3,4,5]
df

df.index = index   # 还原
df

 3.2.2  通过rename方法

dct = {'刘备':'101', 
       '关羽':'102', 
       '张飞':'103', 
       '诸葛亮':'104', 
       '赵云':'105'}    # 定义字典,键为修改前的索引名称,值为修改后的索引名称
df.rename(dct,axis=0)

df

df.rename(index=dct,inplace=True)       # inplace = True  表示将修改后的数据在原来变量修改
df

4.修改数据

4.1  修改整行数据

df.index = index
df

df.loc['张飞'] = [100,95,90,85]
df

4.2  修改整列数据

df.loc[:,'英语'] = [95,94,93,92,91]
df

 

 4.3  修改张飞的各科成绩

  • 各科均加10分
df.loc['张飞'] = df.loc['张飞'] + 10
df

 

 4.4  修改张飞的语文成绩

df.loc['张飞','语文'] = 102
df

 4.5  修改第1行第1列数据

  • 使用iloc方法
df.iloc[0,0] = 120
df

 

 4.6  修改整列数据,第1列

  • 使用iloc方法
df.iloc[:,0] = [130,110,105,130,110]
df

 

 4.7  修改整行数据,第1行

  • 使用iloc方法
df.iloc[0,:] = [120,80,100,90]
df

 

df.iloc[0] = [100,100,100,100]
df

 

 5.删除数据

5.1  删除列数据

  • 传输列表,则删除多列
df

df.drop(columns='数学')     # 默认不会修改原数据,设置inplace=True则修改原数据

df.drop(labels='数学',axis=1)

 5.2  删除行数据

  • 传输列表,则删除多行
df.drop(index='张飞')

 

df.drop(labels='张飞',axis=0)

 5.3  删除指定条件的行

5.3.1  删除“物理”等于70或79的行

df['物理'].isin([70,79])      # 值判断
刘备     False
关羽      True
张飞     False
诸葛亮    False
赵云      True
Name: 物理, dtype: bool
df[df['物理'].isin([70,79])]     # 筛选符合的

df[df['物理'].isin([70,79])].index      # 获取行索引
Index(['关羽', '赵云'], dtype='object')
df.drop(index=df[df['物理'].isin([70,79])].index)      # 根据获取的行索引删除行

 5.3.2  删除“语文”小于120的行

df['语文'] < 120
刘备      True
关羽      True
张飞      True
诸葛亮    False
赵云      True
Name: 语文, dtype: bool
df[df['语文'] < 120].index
Index(['刘备', '关羽', '张飞', '赵云'], dtype='object')
df.drop(index=df[df['语文'] < 120].index)

七、数据清洗

import pandas as pd

1.导入数据

df = pd.read_excel('./data/demo_07.xlsx', sheet_name='Sheet1')
df

2.  查看是否缺失 

2.1  查看字段信息

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14 entries, 0 to 13
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   用户ID    14 non-null     object        
 1   付款金额    14 non-null     float64       
 2   产品数量    11 non-null     float64       
 3   产品名称    12 non-null     object        
 4   类别      9 non-null      object        
 5   订单付款时间  14 non-null     datetime64[ns]
dtypes: datetime64[ns](1), float64(2), object(3)
memory usage: 800.0+ bytes

2.2  查看每列的空值数量

df.isnull().sum()
用户ID      0
付款金额      0
产品数量      3
产品名称      2
类别        5
订单付款时间    0
dtype: int64

2.3  查看每列是否存在空值

df.isnull().any()    # 返回值是True表示存在空值
用户ID      False
付款金额      False
产品数量       True
产品名称       True
类别         True
订单付款时间    False
dtype: bool

2.4  判断每个元素是否非空

df.notnull()

#查看每列是否都不存在空值
df.notnull().all()    # 值为True表示该列无空值
用户ID       True
付款金额       True
产品数量      False
产品名称      False
类别        False
订单付款时间     True
dtype: bool

3.  处理缺失值

3.1  填充缺失值方法

  • 均值(mean)
  • 众数(mode)
  • 中位数(median)

3.2  众数填充

df

df['产品数量'].mode()    # 返回值为一个数据结构
0    5.0
dtype: float64
df['产品数量'].mode()[0]   # 获得第一个众数
5.0
df['产品数量'].mode()[0].mean()    # 获得多个众数的均值
5.0
# 用第一个众数填充
mode = df['产品数量'].mode()[0]
df['产品数量'].fillna(mode)     # 不修改原表数据,需要重新赋值
0     3.0
1     5.0
2     4.0
3     5.0
4     5.0
5     6.0
6     7.0
7     5.0
8     5.0
9     6.0
10    3.0
11    5.0
12    5.0
13    5.0
Name: 产品数量, dtype: float64

3.3  频数最高的“类别”填充

most = df['类别'].mode()[0]
df['类别'].fillna(most)
0     优选
1     优选
2     优选
3     优选
4     优选
5     普通
6     普通
7     优选
8     优选
9     优选
10    优选
11    优选
12    优选
13    优选
Name: 类别, dtype: object

3.4  向前/向后填充

# ffill:向前填充
df['类别'].fillna(method='ffill')
0     优选
1     优选
2     优选
3     优选
4     优选
5     普通
6     普通
7     优选
8     优选
9     优选
10    优选
11    优选
12    优选
13    优选
Name: 类别, dtype: object
# bfill:向后填充
df['类别'].fillna(method='bfill')
0      优选
1      优选
2      优选
3      优选
4      普通
5      普通
6      普通
7      优选
8      优选
9      优选
10     优选
11    NaN
12    NaN
13    NaN
Name: 类别, dtype: object

3.5  删除缺失值

# 删除存在空值的行,整表判断
df.dropna()   # 不修改原数据

# 删除指定列存在空值的行,其中一列存在空值则删除整行
df.dropna(how='any',subset=['产品数量','产品名称'])

# 删除指定列均为空值的行
df.dropna(how='all',subset=['产品数量','类别'])

# 删除小于4个非空值的行
df.dropna(thresh=4)

4.处理重复值

df = pd.read_excel('./data/demo_07.xlsx', sheet_name='Sheet1')
df

 4.1  判断每行是否完全重复

df.duplicated()     # 返回值为True表示改行与前面行的其中一行的所有值完全重复
0     False
1     False
2     False
3     False
4     False
5     False
6     False
7     False
8     False
9     False
10     True
11    False
12    False
13    False
dtype: bool

4.2  删除整行完全重复的数据

df.drop_duplicates(keep='last')    # 保留最后一条,默认keep='first'保留第一条

 4.3  删除指定列的重复数据

  • 保留第1条
df.drop_duplicates(subset='用户ID')    # 按照‘用户ID’判断重复,有重复整行删除,保留重复中的第一条数据

 

  • 保留最后1条
df.drop_duplicates(subset='用户ID',keep='last')

 

 4.4  删除指定多列的重复数据

  • 保留最后1条
df.drop_duplicates(subset=['用户ID','产品名称'],keep='last')

 

 5.  数据筛选

df = pd.read_excel('./data/demo_07.xlsx', sheet_name='Sheet1')

5.1  query方法筛选

  • and、or、not,&、|、~
df

df.query('产品数量 >=2 ')    # 获取产品数量大于等于2的数据

 

#文本筛选
df.query('类别 == "优选"')    # 获取类别为优选的数据,文本筛选,筛选的值需要加引号

#组合筛选
df.query('类别=="优选" and 产品数量 >= 2 ')

 5.2  数值范围筛选

# pd.Series.between(self, left, right, inclusive=True)
df['产品数量'].between(3,5)
0      True
1      True
2      True
3     False
4      True
5     False
6     False
7     False
8      True
9     False
10     True
11     True
12     True
13    False
Name: 产品数量, dtype: bool
df[df['产品数量'].between(3,5)]     # 包含开始结束值

5.3  时间段筛选

  • 12:00:00-23:00:00
# 将时间字段设置为索引
tb = df.set_index('订单付款时间')
tb

 

# pd.Series.between_time(
#     self: 'FrameOrSeries',
#     start_time,
#     end_time,
#     include_start: 'bool_t' = True,
#     include_end: 'bool_t' = True,
#     axis=None,
# )
tb.between_time('12:00:00','23:00:00')   # between_time函数筛选必须设置日期时间索引

 5.4  时间点筛选

  • 22:54:26
# .at_time(time, asof: 'bool_t' = False, axis=None)
tb = df.set_index('订单付款时间')
tb.at_time('22:54:26')

 6.  数据清洗

  • str,dt

6.1  导入数据

df = pd.read_excel('./data/demo_07.xlsx', sheet_name='Sheet2')
df

 

6.2  普通方法筛选

#  .filter(
#     items=None,
#     like: 'Optional[str]' = None,
#     regex: 'Optional[str]' = None,
#     axis=None,
# )
df.filter(items=['用户ID','第1次交易金额'])

 

 6.3  正则方法筛选

df.filter(regex='用户ID|第\d+次交易金额')

df.filter(regex='用户ID|第[1-8]次交易金额')

 

 6.4  字段分列

  • pd.Series.str.split()
# pd.Series.str.split(self, pat=None, n=-1, expand=False)
df['用户信息'].str.split(',',expand=True)           # 设置分隔符时要确定是中文还是英文符号,默认不加入原表

 

#将分裂好的字段插入到表中
df[['性别','年龄']] = df['用户信息'].str.split(',',expand=True)
df

 6.5  字段合并

  • pd.Series.str.cat()
#pd.Series.str.cat(self, others=None, sep=None, na_rep=None, join='left')
df['性别'].str.cat(df['年龄'],',')
0    女,34
1    男,22
2    女,24
3    男,48
4    男,32
5    男,38
6    女,24
7    女,43
8    女,41
9    男,26
Name: 性别, dtype: object
df['性别'] + ',' + df['年龄']
0    女,34
1    男,22
2    女,24
3    男,48
4    男,32
5    男,38
6    女,24
7    女,43
8    女,41
9    男,26
dtype: object

6.6  内容替换

  • pd.Series.str.replace()
# pd.Series.str.replace(
#     self,
#     pat,
#     repl,
#     n=-1,
#     case=None,
#     flags=0,
#     regex=None,
# )
df['交易金额'] = df['交易金额'].str.replace('元','')
df['交易金额'] = df['交易金额'].astype(int)     # 修改字段类型为整型
df['交易金额']
0    43154
1    40398
2    54026
3    58610
4    47180
5    64875
6    52912
7    48676
8    54220
9    50153
Name: 交易金额, dtype: int32

6.7  信息提取

  • pd.Series.str.extract()
#pd.Series.str.extract(self, pat, flags=0, expand=True)
#匹配手机号
df['手机号码'] = df['联系方式'].str.extract(pat='(\d{11})',expand=True)
df['手机号码']
0    15985958961
1    13551067802
2    13682396462
3    18615205809
4    13862393688
5    13717850943
6    13524312139
7    18914085419
8    15674526730
9    15676911440
Name: 手机号码, dtype: object
#匹配邮箱
df['电子邮箱'] = df['联系方式'].str.extract(pat='(\w+@[\w\.]+)')
df['电子邮箱']
0     dingqiang@junliang.cn
1      mingkong@hotmail.com
2            gujuan@juan.cn
3        chaoding@yahoo.com
4    xiulangong@hotmail.com
5         wei15@hotmail.com
6         lijiang@gmail.com
7     xiulanpan@hotmail.com
8          jing70@gmail.com
9       qiangfu@zhaoren.net
Name: 电子邮箱, dtype: object

6.8  爆炸序列

  • 一行拆分成多行
tb = df[['用户ID','产品清单']].copy()
tb

# 先转换为列表,再爆炸序列
tb['产品清单'] = tb['产品清单'].str.split(',',expand=False)
tb['产品清单']
0    [产品D, 产品C]
1    [产品E, 产品A]
2    [产品D, 产品E]
3    [产品D, 产品B]
4    [产品A, 产品C]
5    [产品A, 产品D]
6    [产品D, 产品A]
7    [产品C, 产品D]
8    [产品A, 产品B]
9    [产品B, 产品D]
Name: 产品清单, dtype: object
tb = tb.explode(column='产品清单')
tb

 6.9  文本聚合

  • 多行合并成一行
tb = tb.groupby('用户ID').agg(lambda x: ','.join(x))
tb

 

tb.reset_index()   # 将索引设置为字段并生成一个新的索引

八、索引设置

import pandas as pd

1.  Series重置索引

1.1  创建Series对象

s1 = pd.Series(
    data=[88, 60, 75],
    index=[1, 2, 3])
s1
1    88
2    60
3    75
dtype: int64

1.2  重置索引操作

  • 新索引:[1, 2, 3, 4, 5]
  • 新索引的长度大于原索引,则以NaN填充
s2 = s1.reindex([1,2,3,4,5])
s2
1    88.0
2    60.0
3    75.0
4     NaN
5     NaN
dtype: float64

2.  DataFrame重置索引

2.1  创建DataFrame对象

data = [[110, 105, 99],
        [105, 88, 115],
        [109, 120, 130]]
index = ['A001', 'A003', 'A005']
columns = ['语文', '数学', '英语']
df = pd.DataFrame(
    data=data,
    index=index,
    columns=columns)
df

 2.2  重置行列索引

#  .reindex(
#     labels=None,
#     index=None,
#     columns=None,
#     axis=None,
#     method=None,
#     copy=True,
#     level=None,
#     fill_value=nan,
#     limit=None,
#     tolerance=None,
# )
index = ['A001','A002','A003','A004','A005','A006']
columns = ['语文','数学','英语','物理']
tb = df.reindex(index=index, columns=columns)
tb

#reindex      对索引重新赋值
#set_index     将某字段设置为索引
#reset_index    重置索引从0开始


df = pd.read_excel('./data/demo_08.xlsx')
df

#将用户ID设置为索引
tb = df.set_index('用户ID')
tb.head()

tb = tb.reset_index()
tb.head()

九、数据排序

import pandas as pd

1.  导入数据

df = pd.read_excel('./data/demo_09.xlsx')
df

2.  按一列排序

#  .sort_values(
#     by,
#     axis=0,
#     ascending=True,
#     inplace=False,
#     kind='quicksort',
#     na_position='last',
#     ignore_index=False,
#     key: 'ValueKeyFunc' = None,
# )
df.sort_values(by='销量',ascending=False)           
#ascending=True 升序
#ascending=False 降序 

df.sort_values(by='销量',ascending=False,ignore_index=True) #ignore_index=True 重置索引

3.  按多列排序 

  • 排序方式相同,均为升序或降序
df.sort_values(by=['大区','销量'],ascending=False)

4.  按多列排序

  • 排序方式不同,一列升序一列降序
df.sort_values(by=['大区','销量'],ascending=[True,False])

5.  对分组统计结果排序

#分组聚合
df.groupby('大区')['销量'].sum().reset_index()

#排序
df.groupby('大区')['销量'].sum().reset_index().sort_values(by='销量',ascending=False,ignore_index=True)

 

6.  rank方法排序

  • method : {'average', 'min', 'max', 'first', 'dense'}
#  .rank(
#     axis=0,
#     method: 'str' = 'average',
#     numeric_only: 'Optional[bool_t]' = None,
#     na_option: 'str' = 'keep',
#     ascending: 'bool_t' = True,
#     pct: 'bool_t' = False,
# )
df['排名(average)'] = df['销量'].rank(method='average',ascending=False)
# 类似于SQL的rank
df['排名(min)'] = df['销量'].rank(method='min',ascending=False)
df['排名(max)'] = df['销量'].rank(method='max',ascending=False)
#类似于SQL的row_number
df['排名(first)'] = df['销量'].rank(method='first',ascending=False)
#类似于SQL的dense_rank
df['排名(dense)'] = df['销量'].rank(method='dense',ascending=False)
df

 

#将数据导到excel文件
df.to_excel('./排名.xlsx')

产品名称

价格

销量

大区

排名(average)

排名(min)

排名(max)

排名(first)

排名(dense)

1

产品A0030

59.8

2355

华北

1

1

1

1

1

0

产品A0045

89.8

1300

华南

2

2

2

2

2

9

产品A0099

69.8

888

华中

3.5

3

4

3

3

14

产品A0044

79.8

888

华北

3.5

3

4

4

3

13

产品A0072

69.8

663

华南

5

5

5

5

4

8

产品A0078

59.8

625

华东

6

6

6

6

5

15

产品A0034

99.8

559

华中

7

7

7

7

6

4

产品A0079

69.8

541

华西

8

8

8

8

7

19

产品A0018

79.8

456

华南

9

9

9

9

8

25

产品A0090

69.8

354

华南

10

10

10

10

9

10

产品A0031

79.8

333

华西

11

11

11

11

10

20

产品A0065

79.8

322

华北

12

12

12

12

11

16

产品A0032

128

281

华西

13

13

13

13

12

7

产品A0010

79.8

271

华南

14

14

14

14

13

26

产品A0026

79.8

248

华东

15

15

15

15

14

11

产品A0094

79.8

241

华东

16

16

16

16

15

17

产品A0036

79.8

148

华东

17

17

17

17

16

23

产品A0077

69.8

129

华西

18

18

18

18

17

3

产品A0073

89.8

120

华中

22.5

19

26

19

18

5

产品A0068

79.8

120

华中

22.5

19

26

20

18

6

产品A0098

69.8

120

华西

22.5

19

26

21

18

12

产品A0042

59.8

120

华北

22.5

19

26

22

18

18

产品A0071

49.8

120

华北

22.5

19

26

23

18

21

产品A0059

69.8

120

华东

22.5

19

26

24

18

22

产品A0041

79.8

120

华中

22.5

19

26

25

18

24

产品A0058

69.8

120

华北

22.5

19

26

26

18

2

产品A0067

89.8

110

华东

27

27

27

27

19

十、pandasql

import pandas as pd
from pandasql import sqldf
# pip install pandasql
# sqlite3数据库SQL语言


#设置全局变量
pysqldf = lambda q: sqldf(q, globals())


#读取df
df = pd.read_excel('./data/demo_09.xlsx')


df.head()

 

# 编写sql
sql = '''

select 大区, sum(销量) as 销量
from df 
where 产品名称='产品A0045'
group by 大区

'''


#运行sql语句
pysqldf(sql)

sql = '''

select 大区, sum(销量) as 销量
from df 
group by 大区
having sum(销量) > 1500
order by sum(销量) desc


'''
#where 分组前的筛选
#having 分组后的筛选


pysqldf(sql)

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值