目录

  • 一、dataframe增删改查
  • 1.查询操作
  • 2.增加操作
  • 3.修改操作
  • 4.删除操作
  • 二、Pandas统计分析
  • 三、案例
  • 最火菜品案例
  • 菜品缺失值处理案例


一、dataframe增删改查

1.查询操作

上一篇文章含dataframe的直接索引,本文将介绍1个新的索引方式loc与iloc。

loc方式:只能使用名称 ---同时索引
iloc方式:只可以使用下标
import pandas as pd

# 直接索引方式:先列后行

# 使用loc 、iloc进行同时对行列索引

# 加载数据
detail = pd.read_excel('./meal_order_detail.xlsx')
# 将行名称进行重新赋值
index = ['index_' + str(tmp) for tmp in detail.index]
# 属性重新赋值
detail.index = index
print('detail:\n', detail)
print('detail的列索引:\n', detail.columns)
print('*' * 100)

# loc方式:只能使用名称 ---同时索引
# 获取 dishes_name
# print('获取单列数据:\n', detail.loc[:, 'dishes_name'])

# # 对loc使用下标 ---报错
# print('获取单列数据:\n', detail.loc[0:2, 'dishes_name']) # 错误的

# 获取 多列数据 ---列名列表
# print('获取多列数据:\n', detail.loc[:, ['dishes_name', 'counts', 'amounts']])

# 获取多列数据的指定行
# print('获取多列数据的指定行:\n', detail.loc['index_2749':'index_2759', ['dishes_name', 'counts', 'amounts']])


# iloc方式:只可以使用下标
# 获取单列数据---使用名称---报错
# print('获取单列数据:\n', detail.iloc[:, 'dishes_name']) # 错误的

# 获取单列数据
# print('获取单列数据:\n', detail.iloc[:, 5])

# 获取多列数据 --下标列表--三列
# print('获取多列数据:\n', detail.iloc[:, [5, 7, 8]])
# 获取多列---下标切片---4列
# print('获取多列数据:\n', detail.iloc[:, 5:9])

# 直接索引方式:先列后行 -----效率比较高
# 同时索引方式:loc/iloc ----大的平台封装较多

2.增加操作

查询的表对象['next_year_age'] = 18
# dataframe增加 ---增加行 ---增加更多新的数据 ---数据合并

# dataframe增加 ---增加列 ---给已有的数据增加新的属性
import pandas as pd

# 加载数据
users = pd.read_excel('./users.xlsx')
print('users:\n', users)
print('users的列索引:\n', users.columns)
print('*' * 100)

# 给users新增加一列 next_year_age
# 直接增加
# users['next_year_age'] = 18
#
# print('增加下一年年龄之后的结果为:\n', users)
# 整列都变为18岁
# 整列数据都一样 ---不同的数据在该列上表现都一样
# 研究青少年的身高体重 ---年龄18岁--->18岁青年的身高提高

# 整列数据赋值同样的值 ---工作基本不用,除非都赋值为0,进行占位
# 增加新的列---一般都是通过已知的列---获取新的列
users['next_year_age'] = users['age'] + 1
print('增加下一年年龄之后的结果为:\n', users)

3.修改操作

查询的表对象.loc[要替换的内容, 替换字段] = 替换值
import pandas as pd

# 修改---对已存在的数据进行重新赋值

# 加载数据
users = pd.read_excel('./users.xlsx')
print('users:\n', users)
print('users的列索引:\n', users.columns)
print('*' * 100)

# 对 age 列进行修改
# users['age'] = 18
# print('修改之后的结果:\n', users)

# 该列所有的数据 --->变成一样的
# 满足条件的才进行修改
# 将users里面 年龄都为偶数的 修改为 99岁
# (1) 循环遍历 + if条件判断 ---->可行的
# (2) bool数组索引操作
# a、找到哪些数据 age 是偶数的
# bool_mask = users['age'] % 2 == 0
# print('bool_mask:\n', bool_mask)
# print('*' * 100)
# # b、将这些对应的年龄修改为 99---重新赋值
# users.loc[bool_mask, 'age'] = 99
# print('修改之后的结果:\n',users)

# 修改:将users里面的sex列 为男 修改为 帅哥
# 修改:将users里面的sex列 为女 修改为 靓妹
# a、找到满足条件的
bool_mask_1 = users['sex'] == '男'
bool_mask_2 = users['sex'] == '女'
# b、对满足条件的重新赋值
users.loc[bool_mask_1, 'sex'] = '帅哥'
users.loc[bool_mask_2, 'sex'] = '靓妹'

print('修改之后的结果:\n',users)

4.删除操作

drop方法
查询的表对象.drop(labels=[要删除的字段], axis=1, inplace=True)

	labels --指定删除的行名称、列名称
	axis ---> 0 --删除行   ----1 删除列
	inplace --是否对原df产生影响
import pandas as pd

# 删除---删除列、删除行 ---直接干掉

# drop

# 以users为例进行删除
users = pd.read_excel('./users.xlsx')
print('users:\n', users)
print('users的列索引:\n', users.columns)
print('*' * 100)

# 删除
# labels --指定删除的行名称、列名称
# axis ---> 0 --删除行   ----1 删除列
# ---注意:当axis=0,此时labels 必须为行名称; 当axis=1,此时,labels必须为列名称
# inplace --是否对原df产生影响
# ----如果为True,直接在原df上进行删除
# ----如果为False,不会对原df产生影响,会返回一个删除之后的结果
# users.drop(labels=['sex', 'poo', 'age'], axis=1, inplace=True)
# res = users.drop(labels=['sex', 'poo', 'age'], axis=1, inplace=False)
# print('删除之后的结果:\n', users.shape)
# print('删除之后的结果:\n',res)

# 删除指定的行
# users.drop(labels=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], axis=0, inplace=True)
# print('删除之后的结果为:\n',users.shape)

# # 删除满足条件的
# # 删除 sex列为男的这些行数据
# # a、找到满足条件的 ---bool数组
# bool_mask = users['sex'] == '男'
# # 找到满足条件的行名称
# labels = users.loc[bool_mask, :].index
# # b、删除
# users.drop(labels=labels, axis=0, inplace=True)
# print('删除之后的结果:\n', users)


# 保留法
# 删除满足条件的--->可以理解为:保存不满足条件的
# 删除 sex列为男的这些行数据 --->可以理解为:保存不为男的数据
# 保存不为男的数据 --->选中不为男的数据
# # bool数组
# # a、先找到不为男的 ---bool数组
# bool_mask = users['sex'] != '男'
# # b、保存 ---保留True的,干掉False的
# users = users.loc[bool_mask, :]
# print('删除之后的结果为:\n',users)

# 存在这样的数据
# 存在不同颜色帽子(绿色、红色、白色、黑色) ---不同颜色帽子 --火热程度不同
# 绿色--基本没人买
# 白色--基本没人买
# 红色--基本没人买
# 查看黑色帽子的销售状况
# 删除绿色、红色、白色帽子数据 --->保留黑色的帽子

二、Pandas统计分析

回顾1下numpy当中的统计学函数:

python dataframe删除相同的行索引_数据分析


Pandas 中的统计学函数:

python dataframe删除相同的行索引_数据_02

import pandas as pd
import numpy as np

# 加载数据
detail = pd.read_excel('./meal_order_detail.xlsx')
print('detail:\n', detail)
print('detail的列名:\n', detail.columns)
print('detail的每一列元素的类型:\n', detail.dtypes)
print('*' * 100)

# 对detail 中的 amounts 列进行统计指标
# max(最大值) min(最小值) mean(均值) median(中位数)
# std(标准差) var(方差) ptp(极差) idxmax(最大值下标)  idxmin(最小值下标)

# print('获取amounts列的最大值:', detail.loc[:, 'amounts'].max())  # np.max(arr)
# print('获取amounts列的最小值:', detail.loc[:, 'amounts'].min())  # np.min(arr)
# print('获取amounts列的均值:', detail.loc[:, 'amounts'].mean())
# print('获取amounts列的中位数:', detail.loc[:, 'amounts'].median())


# print('获取amounts列的标准差:', detail.loc[:, 'amounts'].std())
# print('获取amounts列的方差:', detail.loc[:, 'amounts'].var())
# print('获取amounts列的极差:', detail.loc[:, 'amounts'].ptp())  # max 178 - min 1
# print('获取amounts列的最大值下标:', detail.loc[:, 'amounts'].idxmax())
# print('获取amounts列的最小值下标:', detail.loc[:, 'amounts'].idxmin())


# mode(众数)
# 出现次数最多的数 --可能出现多次,但是至少有一个
# print('获取amounts列的众数:\n', detail.loc[:, 'amounts'].mode())
# print('获取amounts列的众数:\n', detail.loc[:, 'amounts'].mode()[0])  # 可以通过行下标来获取具体的众数的值
# 获取amounts列的众数:
#  0    35
# dtype: int64
# print('获取amounts列的众数:\n', type(detail.loc[:, 'amounts'].mode()))
#  <class 'pandas.core.series.Series'>

# 假设存在序列 ---[1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5] --->众数
# 1出现4次  2出现4次  3出现4次  4出现4次 5出现1次
# 0  1
# 1  2
# 2  3
# 3  4
# 4个众数  # 前面的0 1 2 3 -->行索引

# count --->非空数据的数量
# print('获取amounts列的非空数据的数目:', detail.loc[:, 'amounts'].count())
# # #
# # print('获取bar_code列的非空数据的数目:', detail.loc[:, 'bar_code'].count())
# # # 结果为0 ---->说明bar_code列整列都为缺失值

# # quantile---分位数
# # 中位数---->50%分位数
# # 生成一个 [0 0.25 0.5 0.75 1.0]
# q = np.arange(0, 1.0 + 0.25, 0.25)
# print('获取amounts列的分位数:\n', detail.loc[:, 'amounts'].quantile(q=q))
# # 获取amounts列的分位数:
# #  0.00      1.0
# # 0.25     25.0
# # 0.50     35.0
# # 0.75     56.0
# # 1.00    178.0
# # Name: amounts, dtype: float64

# describe ---统计描述--一次可以统计出多个结果
# 8中结果
# 非空数据的数量
# 均值
# 标准差
# 最小值、25%分位数、50%分位数、75%分位数、最大值 ---分位数
# print('获取amounts列的统计描述:\n', detail.loc[:, 'amounts'].describe())

# pandas也可以对于非数值型数据进行统计描述 ---一次返回对个结果
# 对 dishes_name进行统计描述
# 返回4种结果
# 非空数据的数量
# 去重之后所剩下的数量
# 众数
# 众数出现的频次
# print('获取dishes_name列的统计描述:\n', detail.loc[:, 'dishes_name'].describe())

# # 如果以后遇到 统计众数--mode/describe(需要注意:类型必须是非数值型)
# # 如果想要统计一列数值型数据 ---众数、及众数出现的次数
# # ---->将数值型的数据 转化类型 ---->category类型(类别型)
# # 想要统计detail中的amounts单价列的 众数、及该众数出现的次数
# # 转化类型 ----astype
# detail.loc[:, 'amounts'] = detail.loc[:, 'amounts'].astype('category')
# print('detail的类型:\n', detail.dtypes)
# print('*' * 100)

# # 进行统计描述
# print('获取amounts列的众数、及其频次:\n', detail.loc[:, 'amounts'].describe()[['top', 'freq']])

# value_counts ---统计某列各个元素出现的次数。
# print('获取dishes_name列的不同元素出现的次数:\n', pd.value_counts(detail.loc[:, 'dishes_name']))

三、案例

最火菜品案例

查询的数据表:

python dataframe删除相同的行索引_python_03

实现效果:查询最点餐最多的菜品

代码实现:

# 以detail为例,统计该店铺中的最火的菜品?以及该菜品出现的次数?

import pandas as pd

# 加载数据
detail = pd.read_excel('./meal_order_detail.xlsx')
print('detail:\n', detail)
print('detail的列索引:\n', detail.columns)

# 最火的菜品?? --->出现次数最多的菜品名单 ---->菜品名称的众数
# 最火菜品出现的次数---->菜品名称的众数的出现的次数

# 统计众数以及众数出现的次数----describe对于非数值型数据的统计
# 对于菜品名称进行describe统计描述
# print('最火的菜品为:', detail.loc[:, 'dishes_name'].describe()['top'])
# print('最火的菜品出现的次数为:', detail.loc[:, 'dishes_name'].describe()['freq'])

# 最火的菜品为: 白饭/大碗
# 最火的菜品出现的次数为: 92

# 白饭/大碗 ---不算菜品,而算主食 ----也无法做招牌菜品、折扣菜品
# 先删除掉 白饭/大碗 ---然后再进行 describe 统计描述
# 如何确定 白饭/大碗?? --bool数组
bool_mask = detail.loc[:, 'dishes_name'] == '白饭/大碗'
# 确定 白饭/大碗 的行名称
labels = detail.loc[bool_mask, :].index
# 删除---drop
detail.drop(labels=labels, axis=0, inplace=True)



# 保留法 ---保留非 白饭/大碗 的数据
# 先确定 非白饭/大碗 行
# bool_mask = detail.loc[:, 'dishes_name'] != '白饭/大碗'
# # 选中
# detail = detail.loc[bool_mask, :]
#
print('删除 白饭/大碗 之后的结果为:\n', detail.shape)



# # 假设你不知道你要统计的列的类型---统计非数值型数据的describe
# # 将你要统计的列 转化为 category
detail.loc[:, 'dishes_name'] = detail.loc[:, 'dishes_name'].astype('category')

# 再去进行describe统计描述
print('最火的菜品为:', detail.loc[:, 'dishes_name'].describe()['top'])
print('最火的菜品出现的次数为:', detail.loc[:, 'dishes_name'].describe()['freq'])

# 最火的菜品为: 凉拌菠菜
# 最火的菜品出现的次数为: 77

运行结果:

python dataframe删除相同的行索引_数据分析_04

菜品缺失值处理案例

查询的数据表:

python dataframe删除相同的行索引_python_03

**实现效果:删除value都为NIA的列 **

代码实现:

# 如果整列数据都是一样的 ---> 不同的数据在该列的表现都是一样

# 如果整列数据都是缺失的 --->整列数据对结果毫无意义 ---删除
import pandas as pd

detail = pd.read_excel('./meal_order_detail.xlsx')
print('detail:\n', detail)
print('detail的列索引:\n', detail.columns)

# 以 detail表为例,删除detail中整列都是缺失的 这些列
# 暂时无法判断整列都是缺失的
# 我们可以统计出整列数据中的非空数据的数目
# 如果你统计出来某列的数据的 非空数据的数目 = 0 --->说明整列数据 都是缺失的


# 删除法
# # 定义一个删除列表
drop_list = []

for column in detail.columns:
    # 对每一列进行统计 count
    res = detail.loc[:, column].count()
    if res == 0:
        # 将 column 加入到 drop_list
        drop_list.append(column)

# drop_list --->需要删除的列的名称列表
print('drop_list:\n', drop_list)
print('*' * 100)

# # 删除法
detail.drop(labels=drop_list, axis=1, inplace=True)
print('删除整列数据为空的之后的结果为:\n', detail)

# # 保留法
# # 保留 整列至少含有一个数据的列
# # 构建保留的列表
# save_list = []
#
# for column in detail.columns:
#     # 对每一列进行统计 count
#     res = detail.loc[:, column].count()
#     # 判断
#     if res > 0:
#         # 将column加入到 save_list
#         save_list.append(column)
#
# print('save_list:\n', save_list)
#
# # 筛选
# detail = detail.loc[:, save_list]
# print('删除整列为空的结果:\n',detail)

打印结果:

python dataframe删除相同的行索引_python_06


python dataframe删除相同的行索引_数据分析_07