欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【第4章】4.2DataFrame常用操作

程序员文章站 2022-03-02 22:25:13
...

DataFrame 的常用操作

dataframe 的常用属性

  1. 索引--------index
  2. 元素-------values
  3. 列名------columns
  4. 数据类型----dtypes

索引

from sqlalchemy import create_engine
import pandas as pd
engine = create_engine('mysql+pymysql://root:[email protected]/testdb?charset=utf8') # 创建数据库链接
detail = pd.read_sql_table('meal_order_detail1',con=engine) # 已经导入数据库的数据
print('索引:',detail.index)
索引: RangeIndex(start=0, stop=2779, step=1)

元素

print('元素:',detail.values)
元素: [['2956' '417' '610062' ... 'NA' 'caipu/104001.jpg' '1442']
 ['2958' '417' '609957' ... 'NA' 'caipu/202003.jpg' '1442']
 ['2961' '417' '609950' ... 'NA' 'caipu/303001.jpg' '1442']
 ...
 ['6756' '774' '609949' ... 'NA' 'caipu/404005.jpg' '1138']
 ['6763' '774' '610014' ... 'NA' 'caipu/302003.jpg' '1138']
 ['6764' '774' '610017' ... 'NA' 'caipu/302006.jpg' '1138']]

列名

print('列名:',detail.columns)
列名: Index(['detail_id', 'order_id', 'dishes_id', 'logicprn_name',
       'parent_class_name', 'dishes_name', 'itemis_add', 'counts', 'amounts',
       'cost', 'place_order_time', 'discount_amt', 'discount_reason',
       'kick_back', 'add_inprice', 'add_info', 'bar_code', 'picture_file',
       'emp_id'],
      dtype='object')

数据类型

print('数据类型:',detail.dtypes)
数据类型: detail_id                    object
order_id                     object
dishes_id                    object
logicprn_name                object
parent_class_name            object
dishes_name                  object
itemis_add                   object
counts                      float64
amounts                     float64
cost                         object
place_order_time     datetime64[ns]
discount_amt                 object
discount_reason              object
kick_back                    object
add_inprice                  object
add_info                     object
bar_code                     object
picture_file                 object
emp_id                       object
dtype: object

其他的属性等

  1. 元素个数------size
  2. 维度数--------ndim
  3. 数据形状(行列数目)------shape
print('元素个数:',detail.size)
print('维度数:',detail.ndim)
print('数据形状,',detail.shape)
元素个数: 52801
维度数: 2
数据形状, (2779, 19)

特殊场景的T—转置(行列转换)

  • .T.shape
print('转置前数据形状:',detail.shape)
print('转置后数据形状:',detail.T.shape) # 通过查看数据形状(行列数目)来验证结果 
转置前数据形状: (2779, 19)
转置后数据形状: (19, 2779)

查改增删 DataFrame 数据

  1. 查看 DataFrame 数据
  • 字典访问----单列数据
  • 访问属性的方式访问------单列数据
  • 单列多行
  • 多列多行
  • 多行
  • head() 和 tail()访问多行
  • loc, iloc 单列切片
  • loc, iloc 多列切片
  • 花式切片
  • 条件切片
  • 切片比较
  1. 更改 DataFrame 数据
  2. 增添 DataFrame 数据
  3. 删除 行 / 列 数据
  • 删除某列
  • 删除某几行

描述分析 DataFrame 数据

字典访问

  • DataFrame 的单列数据为一个 Series
order_id = detail['order_id'] # 某列
print('order_id的形状:','\n',order_id.shape)
order_id的形状: 
 (2779,)

属性访问的方式访问

  • 可能存在 列名与 pandas 的某些方法重名的问题---------如果会造成程序混乱------是不建议使用的
dishes_name = detail.dishes_name
print('订单中 dishes_name 的形状为:','\n',dishes_name.shape)
订单中 dishes_name 的形状为: 
 (2779,)

单列多行数据获取

  • xxx [ ’ 列名 ’ ] [ n : m ](前闭后开型)
dishes_name5 = detail['dishes_name'][:5]
print('dishes_name 的前5个元素:','\n',dishes_name5)
dishes_name 的前5个元素: 
 0     蒜蓉生蚝
1    蒙古烤羊腿
2     大蒜苋菜
3    芝麻烤紫菜
4      蒜香包
Name: dishes_name, dtype: object

多列的多行

  • xxx.[ [ ’ 列1 ’ ,’ 列2 ’ ] ] [ n : m ] (前闭后开)
  • 前面是------列表, 后面是------切片
orderDish = detail[['order_id','dishes_name']][:5]
print('订单中order_id 和 dishes_name 的前5个元素是:','\n',orderDish)
订单中order_id 和 dishes_name 的前5个元素是: 
   order_id dishes_name
0      417        蒜蓉生蚝
1      417       蒙古烤羊腿
2      417        大蒜苋菜
3      417       芝麻烤紫菜
4      417         蒜香包

多行

  • xxx[ : ] [ n : m ] (前闭后开)
  • 就是原来列的字典-----用[:]切片替代即可-------------包括所有的列
order5 = detail[:][1:5]
print('1-4行元素:','\n',order5)
1-4行元素: 
   detail_id order_id dishes_id logicprn_name parent_class_name dishes_name  \
1      2958      417    609957            NA                NA       蒙古烤羊腿   
2      2961      417    609950            NA                NA        大蒜苋菜   
3      2966      417    610038            NA                NA       芝麻烤紫菜   
4      2968      417    610003            NA                NA         蒜香包   

  itemis_add  counts  amounts cost    place_order_time discount_amt  \
1          0     1.0     48.0   NA 2016-08-01 11:07:00           NA   
2          0     1.0     30.0   NA 2016-08-01 11:07:00           NA   
3          0     1.0     25.0   NA 2016-08-01 11:11:00           NA   
4          0     1.0     13.0   NA 2016-08-01 11:11:00           NA   

  discount_reason kick_back add_inprice add_info bar_code      picture_file  \
1              NA        NA           0       NA       NA  caipu/202003.jpg   
2              NA        NA           0       NA       NA  caipu/303001.jpg   
3              NA        NA           0       NA       NA  caipu/105002.jpg   
4              NA        NA           0       NA       NA  caipu/503002.jpg   

  emp_id  
1   1442  
2   1442  
3   1442  
4   1442  

head() 和 tail() 方法获取多行

  • 默认是访问前后5行
  • 在()内指定行数------------------也可以实现目标行数的访问
print('前5 行:','\n',detail.head())
前5 行: 
   detail_id order_id dishes_id logicprn_name parent_class_name dishes_name  \
0      2956      417    610062            NA                NA        蒜蓉生蚝   
1      2958      417    609957            NA                NA       蒙古烤羊腿   
2      2961      417    609950            NA                NA        大蒜苋菜   
3      2966      417    610038            NA                NA       芝麻烤紫菜   
4      2968      417    610003            NA                NA         蒜香包   

  itemis_add  counts  amounts cost    place_order_time discount_amt  \
0          0     1.0     49.0   NA 2016-08-01 11:05:00           NA   
1          0     1.0     48.0   NA 2016-08-01 11:07:00           NA   
2          0     1.0     30.0   NA 2016-08-01 11:07:00           NA   
3          0     1.0     25.0   NA 2016-08-01 11:11:00           NA   
4          0     1.0     13.0   NA 2016-08-01 11:11:00           NA   

  discount_reason kick_back add_inprice add_info bar_code      picture_file  \
0              NA        NA           0       NA       NA  caipu/104001.jpg   
1              NA        NA           0       NA       NA  caipu/202003.jpg   
2              NA        NA           0       NA       NA  caipu/303001.jpg   
3              NA        NA           0       NA       NA  caipu/105002.jpg   
4              NA        NA           0       NA       NA  caipu/503002.jpg   

  emp_id  
0   1442  
1   1442  
2   1442  
3   1442  
4   1442  
print('后5行:','\n',detail.tail())
后5行: 
      detail_id order_id dishes_id logicprn_name parent_class_name dishes_name  \
2774      6750      774    610011            NA                NA       白饭/大碗   
2775      6742      774    609996            NA                NA         牛尾汤   
2776      6756      774    609949            NA                NA      意文柠檬汁    
2777      6763      774    610014            NA                NA        金玉良缘   
2778      6764      774    610017            NA                NA        酸辣藕丁   

     itemis_add  counts  amounts cost    place_order_time discount_amt  \
2774          0     1.0     10.0   NA 2016-08-10 21:56:00           NA   
2775          0     1.0     40.0   NA 2016-08-10 21:56:00           NA   
2776          0     1.0     13.0   NA 2016-08-10 22:01:00           NA   
2777          0     1.0     30.0   NA 2016-08-10 22:03:00           NA   
2778          0     1.0     33.0   NA 2016-08-10 22:04:00           NA   

     discount_reason kick_back add_inprice add_info bar_code  \
2774              NA        NA           0       NA       NA   
2775              NA        NA           0       NA       NA   
2776              NA        NA           0       NA       NA   
2777              NA        NA           0       NA       NA   
2778              NA        NA           0       NA       NA   

          picture_file emp_id  
2774  caipu/601005.jpg   1138  
2775  caipu/201006.jpg   1138  
2776  caipu/404005.jpg   1138  
2777  caipu/302003.jpg   1138  
2778  caipu/302006.jpg   1138  
print('指定访问前 4 行 ','\n',detail.head(4))
指定访问前 4 行  
   detail_id order_id dishes_id logicprn_name parent_class_name dishes_name  \
0      2956      417    610062            NA                NA        蒜蓉生蚝   
1      2958      417    609957            NA                NA       蒙古烤羊腿   
2      2961      417    609950            NA                NA        大蒜苋菜   
3      2966      417    610038            NA                NA       芝麻烤紫菜   

  itemis_add  counts  amounts cost    place_order_time discount_amt  \
0          0     1.0     49.0   NA 2016-08-01 11:05:00           NA   
1          0     1.0     48.0   NA 2016-08-01 11:07:00           NA   
2          0     1.0     30.0   NA 2016-08-01 11:07:00           NA   
3          0     1.0     25.0   NA 2016-08-01 11:11:00           NA   

  discount_reason kick_back add_inprice add_info bar_code      picture_file  \
0              NA        NA           0       NA       NA  caipu/104001.jpg   
1              NA        NA           0       NA       NA  caipu/202003.jpg   
2              NA        NA           0       NA       NA  caipu/303001.jpg   
3              NA        NA           0       NA       NA  caipu/105002.jpg   

  emp_id  
0   1442  
1   1442  
2   1442  
3   1442  

单列切片

  • loc 是针对 DataFrame 索引名称的切片方法--------------不是索引名称就无法执行
  • 语句 : xxx(dataframe).loc [ 行索引名称 或 条件 ,列索引名称]
  • iloc ------------接受行,列索引位置
  • 语句 : xxx.iloc [ 行索引位置, 列索引位置 ]

loc

dishes_name1 = detail.loc[:,'dishes_name']
print('loc 获取的 dishes_name 列的元素个数是:',dishes_name1.size)
loc 获取的 dishes_name 列的元素个数是: 2779

iloc

dishes_name2 = detail.iloc[:,3] # 提取第 3 列
print('iloc 获取的第 3 列的 size:',dishes_name2.size)
iloc 获取的第 3 列的 size: 2779

多列切片

  • 这里是包括所有的行
  • 多列的列名 或者位置----------作为列表传入就可以了

loc

orderDish1 = detail.loc[:,['order_id','dishes_name']]
print('loc 提取的 order_id 和 dishes_name 的size:',orderDish1.size)
loc 提取的 order_id 和 dishes_name 的size: 5558

iloc

orderDish2 = detail.iloc[:,[1,3]] # 1 行 和 3 行
print('iloc 获取的 1行和 3 行的size:',orderDish2.size)
iloc 获取的 1行和 3 行的size: 5558

花式切片

  • 获取任意数据
  • 任意行列

loc (前闭后闭)

print('order_id 和 dishes_name 的行名是 3 的数据:','\n',detail.loc[3,['order_id','dishes_name']])
order_id 和 dishes_name 的行名是 3 的数据: 
 order_id         417
dishes_name    芝麻烤紫菜
Name: 3, dtype: object
print('order_id 和 dishes_name 的行名是 2,3,4,5,6 的数据','\n',detail.loc[2:6 ,['order_id','dishes_name']]) 
order_id 和 dishes_name 的行名是 2,3,4,5,6 的数据 
   order_id dishes_name
2      417        大蒜苋菜
3      417       芝麻烤紫菜
4      417         蒜香包
5      301         白斩鸡
6      301        香烤牛排

iloc(前闭后开)

print('列为致癌为1 和 3 的行位置是 3 的数据','\n',detail.iloc[3,[1,3]]) 
列为致癌为1 和 3 的行位置是 3 的数据 
 order_id         417
logicprn_name     NA
Name: 3, dtype: object
print('列位置是 1 和 3 行位置是2,3,4的数据是:','\n',detail.iloc[2:5,[1,3]])
列位置是 1 和 3 行位置是2,3,4的数据是: 
   order_id logicprn_name
2      417            NA
3      417            NA
4      417            NA

条件切片

  • loc 内部可以传入表达式----------------返回满足表达式的所有值
  • iloc 不可以接收表达式-----------------返回的是布尔值 Series ----------去除 Series 的 values (.values 属性)就行了

loc

print('order_id 为 458 的dishes_name为:','\n',detail.loc[detail['order_id']=='458',['order_id','dishes_name']])
order_id 为 458 的dishes_name为: 
     order_id dishes_name
145      458       蒜香辣花甲
146      458        剁椒鱼头
147      458     凉拌蒜蓉西兰花
148      458        木须豌豆
149      458        辣炒鱿鱼
150      458        酸辣藕丁
151      458       炝炒大白菜
152      458       香菇鸡肉粥
153      458        干锅田鸡
154      458     桂圆枸杞鸽子汤
155      458       五香酱驴肉
156      458    路易拉菲红酒干红
157      458       避风塘炒蟹
158      458       白饭/大碗

iloc

print('order_id为 458 的第1 和 5 列的数据为:','\n',detail.iloc[(detail['order_id']=='458').values,[1,5]])
order_id为 458 的第1 和 5 列的数据为: 
     order_id dishes_name
145      458       蒜香辣花甲
146      458        剁椒鱼头
147      458     凉拌蒜蓉西兰花
148      458        木须豌豆
149      458        辣炒鱿鱼
150      458        酸辣藕丁
151      458       炝炒大白菜
152      458       香菇鸡肉粥
153      458        干锅田鸡
154      458     桂圆枸杞鸽子汤
155      458       五香酱驴肉
156      458    路易拉菲红酒干红
157      458       避风塘炒蟹
158      458       白饭/大碗

切片比较

  • ix 方法------------像 loc 和 iloc 两种方法的结合
  • 语句 :DataFrame.ix [ 行索引名称 或 位置 或 条件 ,列索引名称 或 位置 ]

ix 方法注意点:

  1. 一律是闭区间
  2. 使用列索引名称--------保证代码可读性
  3. 使用列索引的时候,要注解---------同样是保证代码可读性
  4. ix 在面对数量巨大的任务时,效率低于 loc 和 iloc;ix 方法更加难以控制----------因此建议使用 loc 和 iloc
print('列位置是 5 的 2-6的数据:','\n',detail.ix[2:6,5]) # 列位置是 5
列位置是 5 的 2-6的数据: 
 2     大蒜苋菜
3    芝麻烤紫菜
4      蒜香包
5      白斩鸡
Name: dishes_name, dtype: object

更改 DataFrame 中的数据

  • 原理:将数据提取出来,重新赋值

  • 注意点:更改操作无法撤销,如果更改,需要注意确认,或者进行备份

detail.loc[detail['order_id']=='458','order_id'] = '45800'
print('更改后,order_id = 458 的order_id 为:','\n',detail.loc[detail['order_id']=='458','order_id']) # 更改后应该是无
print('更改后,order_id = 45800 的order_id 为:','\n',detail.loc[detail['order_id']=='45800','order_id'])
更改后,order_id = 458 的order_id 为: 
 Series([], Name: order_id, dtype: object)
更改后,order_id = 45800 的order_id 为: 
 145    45800
146    45800
147    45800
148    45800
149    45800
150    45800
151    45800
152    45800
153    45800
154    45800
155    45800
156    45800
157    45800
158    45800
Name: order_id, dtype: object

给 DataFrame 增添数据 (增加列)

  • 新建一个索引,然后赋值

  • 如果该新建列需要的值都相同,那么可以赋一个常量

新增一列非定值

detail['payment'] = detail['counts'] * detail['amounts'] # 总支付 = 总量 * 单价
print('新增列的前五行:','\n',detail['payment'].head())
新增列的前五行: 
 0    49.0
1    48.0
2    30.0
3    25.0
4    13.0
Name: payment, dtype: float64

新增一列定值

detail['pay_way'] = '支付现金'
print('新增列的前五行:','\n',detail['pay_way'].head())
新增列的前五行: 
 0    支付现金
1    支付现金
2    支付现金
3    支付现金
4    支付现金
Name: pay_way, dtype: object

删除某列或某行数据

  • pandas 提供的 drop 方法

  • 语法:DataFrame.drop ( labels, axis = 0, level = None, inplace = False, errors =’ raise’)

参数名称 说明
labels 接收 string 或 arry。代表要删除的 行 或者 列 的标签,无默认
axis 接收 0 或者 1 ,1代表列操作;0代表行操作
inplace 接收 boolen 。代表操作是否对原数据生效,默认是 False
  • 鉴于这里的行标签是从0开始的整数,可以用到 range()函数

  • range() 函数说明:

  1. range (start, stop [ , step ])
  2. start:表示开始,默认是0------------range(5)==range(0,5); stop:表示结束,并且不包含stop---------range(0,3) = [ 0 , 1 , 2 ],不含 3
  3. step:表示步长,默认是1----------range(0,5)==range(0,5,1)

删除某列

print('删除pay_way 前的列引索(列名):','\n',detail.columns)
detail.drop(labels='pay_way',axis = 1, inplace = True)
print('删除pay_way 后的列引索(列名):','\n',detail.columns)
删除pay_way 前的列引索(列名): 
 Index(['detail_id', 'order_id', 'dishes_id', 'logicprn_name',
       'parent_class_name', 'dishes_name', 'itemis_add', 'counts', 'amounts',
       'cost', 'place_order_time', 'discount_amt', 'discount_reason',
       'kick_back', 'add_inprice', 'add_info', 'bar_code', 'picture_file',
       'emp_id', 'payment', 'pay_way'],
      dtype='object')
删除pay_way 后的列引索(列名): 
 Index(['detail_id', 'order_id', 'dishes_id', 'logicprn_name',
       'parent_class_name', 'dishes_name', 'itemis_add', 'counts', 'amounts',
       'cost', 'place_order_time', 'discount_amt', 'discount_reason',
       'kick_back', 'add_inprice', 'add_info', 'bar_code', 'picture_file',
       'emp_id', 'payment'],
      dtype='object')

删除某几行

print('删除 1- 10行前的detail长度:',len(detail))
detail.drop(labels=range(1,11),axis= 0,inplace = True) # 删除 1-10 行
print('删除 1- 10行后的detail长度:',len(detail))
删除 1- 10行前的detail长度: 2779
删除 1- 10行后的detail长度: 2769

描述分析 DataFrame 数据

  1. 数值型特征的描述性统计
  • Numpy 的描述性统计函数
  • np.mean 函数 pandas 也可以实现
  • describe 方法---------------数值型描述性统计
标号 提供的数值型特征
1 非空值数目 count
2 均值 mean
3 四分位数
4 最大值 max
5 最小值 min
  1. 类别特征的描述性统计
  • 频数统计方法-------DataFrame.value_counts () [ : ] ,可以跟切片取几项
  • describe 方法---------------category 类型的描述性统计
  • astype ( ‘category’ ) 方法强制转换 object 类型为 category 类型
标号 描述性特征
count 非空元素数目
unique 类别的数目
top 数目最多的类别
freq 数目最多的类别的数目

数值型特征的描述性统计

np.mean 函数

import numpy as np
print('amount(单价)的平均值:',np.mean(detail['amounts']))
amount(单价)的平均值: 45.343084145901045

pandas 的 mean() 方法

print('amount的平均值:',detail['amounts'].mean())
amount的平均值: 45.343084145901045

describe 方法

print('counts 和 amounts 的描述系统计:','\n',detail[['counts','amounts']].describe())
counts 和 amounts 的描述系统计: 
             counts      amounts
count  2769.000000  2769.000000
mean      1.111593    45.343084
std       0.626521    36.841316
min       1.000000     1.000000
25%       1.000000    25.000000
50%       1.000000    35.000000
75%       1.000000    56.000000
max      10.000000   178.000000

类别性特征的描述性统计

value_counts 方法

print('dishes_name 的频数统计结果,前十项:','\n',detail['dishes_name'].value_counts()[0:10])
dishes_name 的频数统计结果,前十项: 
 白饭/大碗        91
凉拌**         77
谷稻小庄         72
麻辣小龙虾        65
白饭/小碗        60
五色糯米饭(七色)    58
芝士烩波士顿龙虾     55
焖猪手          55
辣炒鱿鱼         53
水煮鱼          47
Name: dishes_name, dtype: int64

astype( ’ category ’ ) 强制类型转换

detail['dishes_name'] = detail['dishes_name'].astype('category')
print('转变后数据类型:',detail['dishes_name'].dtype) # 用属性
print('describe 对 category 类数据的描述性统计:','\n',detail['dishes_name'].describe())
转变后数据类型: category
describe 对 category 类数据的描述性统计: 
 count      2769
unique      145
top       白饭/大碗
freq         91
Name: dishes_name, dtype: object