python中的第3方工具包pandas功能强大, 日常工作中比如筛选、排序、计算、透视、vlookup、分类汇总等excel常用操作用pandas也能轻松实现;
本文精心整理的pandas数据处理与分析的52个技巧, 100多个知识点, 掌握这些,处理数据不再是难事!
零基础学习python数据分析, 建议安装anaconda, 可通过下面网址安装 : 清华镜像
配套相关基础课程, 理论+实践: 欢迎订阅 →
- 1 导入工具包
-
# pandas 和numpy是两个基础的工具包
-
import numpy
as np
-
import pandas
as pd
-
# matplotlib seaborn是作图工具包
-
import matplotlib.pyplot
as plt
-
import seaborn
as sns
-
# 通过os设置默认路径
-
import os
-
os.chdir(
'C:/Users/用户/Desktop/')
# 桌面的路径
-
# 图表中文显示问题
-
plt.rcParams[
'font.sans-serif']=[
'SimHei']
#用来正常显示中文标签
-
plt.rcParams[
'axes.unicode_minus']=
False
#用来正常显示负号
-
# 不显示预警
-
import warnings
-
warnings.filterwarnings(
'ignore')
- 2 spyder中快捷键
-
# 注释、取消注释
-
Ctrl+
1
-
# 块注释 / 取消块注释
-
Ctrl+
4/
5
-
# 从当前光标所在行开始执行
-
F9
- 3 读取excel数据
-
# 读取文件
-
df = pd.read_excel(
'文件.xlsx')
-
# 读取文件同时筛选需要的列
-
df = pd.read_excel(
'文件.xlsx')[[
'',
'']]
# 读取并筛选几列
-
# 读取特定的工作表
-
df = pd.read_excel(
'文件.xlsx',sheet_name=
'明细')
# 读取某个sheet表
-
# with方法读取
-
with pd.ExcelFile(
'path_to_file.xls')
as xls:
-
df1 = pd.read_excel(xls,
'Sheet1')
-
df2 = pd.read_excel(xls,
'Sheet2')
- 4 读取csv或者txt
-
# 分隔符: \s 表示空白字符; \s+多个空白字符; \r回车; \n换行; \t水平制表符; \v垂直制表符
-
df = pd.read_csv(
'文件.txt',sep=
'\s+',error_bad_lines=
False)
- 5 批量读取同一文件夹下文件方式1
-
for root, dirs, files
in os.walk('.',topdown=
False):
-
print(files)
-
num = len(files) # 获取文件个数
-
data = pd.DataFrame() # 定义一个空的dataframe
-
# 遍历所有文件
-
for i
in range(num):
-
datai = pd.read_excel('./%s' %files[i])
-
datai_len = len(datai)
-
data = data.append(datai) # 添加到总的数据中
-
print('文件%i列, 第%i个表,读取%i行数据,名称:%s'%(len(
data.columns),i,datai_len,files[i])) # 查看是否全部读取,格式是否出错
-
-
data.reset_index(drop=True,inplace=True)
- 6 批量读取同一文件夹下的文件方式2
-
# 导入工具包
-
import pandas
as pd
-
import numpy
as np
-
import os
-
-
# 路径
-
path = 'd:/文件路径/'
-
-
# 文件列表
-
files = []
-
for file
in os.listdir(path):
-
if file.endswith(
".csv"):
-
files.append(path+file)
-
-
# 定义一个空的dataframe
-
data = pd.DataFrame()
-
-
# 遍历所有文件
-
for file
in files:
-
datai = pd.read_csv(file,encoding='gbk')
-
datai_len = len(datai)
-
data = data.append(datai) # 添加到总的数据中
-
print('读取%i行数据,合并后文件%i列, 名称:%s'%(datai_len,len(
data.columns),file.split('/')[-1]))
-
# 查看是否全部读取,格式是否出错
-
# 重置索引
-
data.reset_index(drop=True,inplace=True)
- 7 批量读取同一文件夹下得文件方式3(当txt文件不规范,读取会丢失数据或文件太大时)
-
# 循环读取数据
-
n = 1
-
for file in files:
-
with
open(
file,
'r',
encoding=
'gbk')
as f_input:
-
lisi= []
-
for line
in f_input:
-
lisi.append(
list(line.strip().split(
'|')))
-
-
datai = pd.DataFrame(lisi)
-
datai2 = guolv(datai)
-
data = data.append(datai2)
-
-
print(
'读取第%i个文件,件名%s,文件%i行,文%i列.处理后文件%i行,%i列' %(n,
file,datai.shape[
0],datai.shape[
1],datai2.shape[
0],datai2.shape[
1]))
-
n = n +
1
- 8 文件导出,放在同一工作簿
-
with
pd
.ExcelWriter(
'文件.xlsx')
as
writer:
-
df1
.to_excel(writer, sheet_name=
'文件1')
-
df2
.to_excel(writer, sheet_name=
'文件2')
- 9 文件导出, 分组导出放在同一工作簿
-
writer = pd.ExcelWriter(
'文件.xlsx')
-
for
name , group
in df.groupby(
'名称'):
-
group.to_excel(writer,sheet_name=
name,
index=False)
- 10 文件导出, 分组导出, 放在不同工作簿
-
for
name , group
in df.groupby(
'名称'):
-
group.to_excel(
name+
'.xlsx',
index=False)
- 11 获取当前时间
-
import
time
-
tim = time.strftime(
"%Y-%m-%d%H%M%S", time.localtime())
- 12 保存图片分辨率设置
plt.savefig('名称.png',dpi=150)
- 13 数据查看
-
df
.describe() # 描述统计
-
df
.info() # 基本信息
-
df
.dtypes # 列格式类型
-
df
.head(2) #前
n行
-
df
.tail(2) #后n行
-
df
.shape #维度
-
df
.index #索引
-
df
.columns #列名
-
df
.sample(10) #随机抽样
-
df
.resample() #随机抽样
- 14 行列处理(删除,排序)
-
# 删除列
-
del df[
'变量名']
-
df.drop(
'变量名',axis=
1,inplace=
True)
-
# 删除行
-
df.drop(
'c')
-
# 更改列名
-
df.columns= [
'var1',
'var2',
'var3']
# 列名的个数 = 字段个数
-
df.rename(columns = {
'名称前':
'名称后'},inplace=
True)
# columns 不能少
-
# series中改列名
-
s.rename(
'名称',inplace=
True)
-
# 调整列的顺序
-
df1 = df1[[
'var1',
'var2',
'var3']]
-
# 调整行的顺序
-
df2 = df1.reindex([
'a',
'b',
'c',
'd',
'e'])
# 返回一个新的DataFrame,按新的索引进行排序
- 15 缺失值(查看,替换,计数)
-
# 判断是否是缺失值
-
df
.isnull() #不能省略括号
-
df
.notnull()
-
# 计算缺失值个数
-
s
.isnull()
.value_counts()
-
# 每列缺失值个数
-
df
.isna()
.sum() # 缺失值个数
-
-
# 填充缺失值
-
df
['A']
.fillna(
'缺失数据',inplace=True)
-
data1
.fillna(method=
'pad') # 类似于
excel中用上一个单元格内容批量填充
-
-
# 删除指定列包含缺失值的行
-
data
.dropna(subset=[
"C"],inplace=True) #
[]不能少
-
data
.dropna(how=
"all") # 删除全为空的行
-
data
.dropna(thresh=
2) #删除有效数据小于
2的数据
-
-
# 缺失值个数并排序
-
df
.isnull()
.sum()
.sort_values(ascending=False)
.head()
- 16 重复值(查看,删除)
-
# 不重复项
-
df['A'].unique()
-
df['A'].nunique()
#查看不重复值个数
-
df['A'].unique().tolist()
# 转list
-
df['A'].value_counts()
# 计数
-
# 去重
-
set(data2[
'名称'])
-
-
# 查看重复项,返回True False
-
df.duplicated()
-
# 查看重复的数据
-
data4 = data3[data3.duplicated(subset=
'var1',
keep=
False)]
-
-
# 删除重复项
-
df.drop_duplicates([
'var'],inplace=
True)
-
# 按两列去重
-
data.drop_duplicates(subset=[
'A',
'B'],
keep=
'first',inplace=
True)
-
# 分组计算不重复项个数
-
result = df.groupby([
'var1',
'var2']).agg({
'var3':
'nunique',
'var4':[
'min',
'max']})
- 17 修改格式(格式转换, 百分比, 格式判断)
-
# 改变列的格式(文本型数值改成数值型数值)
-
df[
'var1'] = df[
'var1'].astype(
'int')
# errors = 'ignore'
-
df[
'var1'] = df[
'var1'].astype(np.float)
-
# 多列转换
-
df[[
'user_id',
'merchant_id',
'coupon_id']]=df[[
'user_id',
'merchant_id',
'coupon_id']].astype(str)
-
df.infer_objects()
# 根据数据特征自动转换
-
-
# 百分比格式
-
data[
'B_per%'] = data[
'B_per'].apply(
lambda x:
'%.2f%%' % (x*
100))
-
-
# 判断格式,是否为字符串
-
data[
'var'].apply(
lambda x:isinstance(x,str))
- 18 普通筛选
-
# loc筛选:选择符合条件的行
-
df.loc[df[
"grade"] ==
"B"].head()
-
-
# 选择符合条件的行和特定的列
-
df.loc[df[
"grade"] ==
"B", [
"member_id",
"grade"]].head()
-
# 选择符合条件的行和特定的列,并排序
-
df.loc[df[
"grade"] ==
"B", [
"loan_amnt",
"grade"]].sort([
"loan_amnt"])
-
# 多条件筛选
-
df.loc[[(df[
"gradd"]==
"B") & (df[
"loan_amnt"]>
5000), [
"member_id",
"term" ]].head()
-
# 反选
-
data[~((data.发布时间.isnull()) & (data.实际首试日期 < '2018-11-1'))]
-
# 反转行
-
df.iloc[::
-1, :]
- 19 逻辑判断后筛选
-
# isin筛选
-
df[
"A"].isin([
1,
2,
3])
-
# 多条件
-
df[(df.AAA <=
6) & (df.index.isin([
0,
2,
4]))]
-
# loc和isin组合
-
df.loc[df[
'sepal_length'].isin([
5.8,
5.1])]
-
# 字符串isin
-
df.loc[df[
'grade'].isin([
'北京',
'上海'])]
-
# 字符串开头
-
df[df[
'A'].str.startswith(
'北京')]
-
-
# contains筛选
-
df[df[
'商品名称'].str.contains(
"四件套")]
-
# 多个筛选
-
df_re =df[df[
'公司'].str.contains(
'公司A||公司B')]
-
# 筛选含特殊字符的
-
df[df[
'产业线'].str.contains(
'\?')]
-
# 多条件筛选
-
data[(data[
'var1'].str[
0] ==
'M')&(data[
'var2'].apply(
lambda x : str(x)[
0] ==
'8'))]
-
-
# 索引特殊用法
-
df[[i.endswith(
'A')
for i
in df.index]]
-
-
# 按字符串长度筛选
-
data = df[df[
'名称'].str.len()>
5]
-
-
# 按字符串开头筛选
-
df[df[
'名称'].str[
0] ==
'M']
-
-
# 筛选列
-
data = data.loc[:,~(data.columns.str.contains(
'集团'))]
-
-
# 筛选前几个最大值
-
data = df.iloc[df[
'名称'].nlargest(
3).index]
-
-
# 筛选由汉字开头的数据
-
df = df[df[
'名称'].str.contains(
r'^[\u4e00-\u9fa5]')]
-
-
# 日期不是索引时, 按日期筛选
-
data[data[
'时间'].apply(
lambda x: x.year ==
2019)]
-
data[data[
'时间'].apply(
lambda x: x.strftime(
'%Y%m')==
'202008')]
- 20 分组后筛选
-
# 分组后筛选前2个
-
df2 = df1.groupby([
'class']).head(
2)
-
-
# 分组后筛选第2条或者倒数第2条数据
-
df1.groupby(
'class').apply(
lambda i:i.iloc[
1]
if len(i)>
1
else np.nan)
-
df1.groupby(
'class').apply(
lambda i:i.iloc[
-2]
if len(i)>
1
else np.nan)
-
-
# 分组后按条件筛选
-
data.groupby(
'var1').filter(
lambda x: len(x[x[
'var2']==
'A'])>=
1)
-
data.groupby(
'公司编码').filter(
lambda x:len(x)!=
3)
-
-
# groupby筛选方法1(先分组,然后筛选另一个变量中最小值)
-
df.loc[df.groupby(
'AA')[
'BB'].inxmin()]
-
#groupby筛选方法2:(先排序,分组,然后筛选每一组中的第一个)
-
df.sort_values(by=
'BB').groupby(
'AA',as_index=
False).first()
-
# groupby筛选方法3:groupby与apply结合
-
df.groupby(
'aa').apply(
lambda x : x[
'BB'][x[
'cc'].idxmax()]
-
-
# 分组并排序
-
df[[
'A',
'B']].groupby(
'A').mean().sort_values(
'B',ascending=
False).head()
- 21 替换
-
# 单个替换
-
df[
'判断'].replace([
'B',
'C'],np.nan,inplace=
True)
#支持正则表达式
-
# 多个替换
-
data[
'var'].replace([
'A',
'B'],[
'a',
'b'],inplace=
True)
-
# loc原地替换
-
df1.loc[df[
'sex']==
'female',
'sex'] =
1
-
df1.loc[df[
'sex']==
'male',
'sex'] =
0
-
-
# 字典
-
df.replace({
'female':
1,
'male':
0})
-
# 适合二分法
-
df1[
'sex'] = df1[
'sex'].map(
lambda x:
1
if x==
'female'
else
0)
-
# apply
-
df_zb[
'var'] = df_zb[
'var'].apply(
lambda x: x[:
-1]
if x[
-1].isalpha()
else x)
-
data3[
'var'] = data3[
'var'].apply(
lambda x: x[:
-1]
if x[
-1] ==
's'
else x)
-
-
# np.where
-
data[
'var'] = np.where(data[
'var'] ==
' ',
0,data[
'var'])
- 22 字符串处理
-
print(
'我的名字是%s,今年%i岁,体重%.2f'%(
'小明',
20,
70.1))
-
# 去除空格,改变大小写
-
df[
'term'] = df[
'term'].map(str.strip)
#去除左右两边的空格,strip后面是否带括号
-
df[
'term'] = df[
'term'].str.strip()
-
df[
'term'] = df[
'term'].map(str.lstrip)
#去除左边的空格
-
df[
'term'] = df[
'term'].map(str.rstrip)
#去除右边的空格
-
df[
'term'] = df[
'term'].map(str.upper)
# 改成全部大写
-
df[
'term'] = df[
'term'].map(str.lower)
# 改成全部小写
-
df[
'term'] = df[
'term'].map(str.title)
# 改成首字母大写
-
-
# 去掉所有空格
-
data = data.applymap(
lambda x: x.strip()
if isinstance(x,str)
else x)
- 23 字符串判断
-
# 判断是否为某一特定格式
-
df
['emp_length']
.apply(
lambda
x:
x
.isalpha()) #是否为字母
-
df
['emp_length']
.apply(
lambda
x:
x.
isalnum ()) #是否全未数字或者字母
-
df
['emp_length']
.apply(
lambda
x:
x.
isdigit ()) #是否为数字
- 24 字符串拆分
-
s.str.
split(
'_')
# 拆分,结果是列表
-
s.str.
split(
'_').str.get(
1)
# 拆分后取第一个,可用于生成新变量
-
s.str.
split(
'_').str[
1]
# 拆分后取第一个,可用于生成新变量
-
s.str.
split(
'_', expand=True)
# 拆分,并展开成多列
-
s.str.
split(
'_', expand=True, n=
1)
# 按第一个拆分
-
s.str.rsplit(
'_', expand=True, n=
1)
# 按最后一个拆分
-
data[
'var'] = data[
'var'].str.
split(
'?',expand=True)[
0]
- 25 索引
-
# 把列变成索引
-
df.set_index('时间',inplace=True,
drop =
False)
-
df.set_index([
'r',
's'], inplace =
True)
# r为一级,s为二级
-
-
# 取消层次化索引,将索引变回列
-
df.reset_index(inplace=
True)
-
df.reset_index(
drop=
True,inplace=
True,
level =
None)
-
-
# 按索引排序
-
df.sort_index(inplace=
True,ascending=
False)
-
-
# 更新索引(行、列都可以修改)
-
df2 = df1.reindex([
'a',
'b',
'c',
'd',
'e'])
# 返回一个新的DataFrame,按新的索引进行排序
-
df2 = df1.reindex([
'a',
'b',
'c',
'd',
'e'], fill_value=
0)
-
-
# 多级索引问题(索引可以在行,也可以在列)
-
df.index.names=[
'类型',
'供应商']
# 取名称
-
df.columns.names=[
'类型',
'日期']
# 取名称
-
df1 = df.swaplevel(
'类型',
'日期',axis=
1)
#调整多级索引次序
-
df1 = df.sort_index(
level=
0, axis=
1, ascending=
True,sort_remaining=
False)
# sort_remaining 默认是True
-
df1 = df.sum(axis=
1,
level=
'类型')
# 通过索引对多列进行求和
- 26 排序
-
# na_position对NaN值的处理方式,可以选择first和last两种方式
-
df.sort()
-
# 单列排序
-
df.sort([
"loan_amnt"],ascending=
False)
# 降序
-
# 多列进行排序,加入一个列表
-
df.sort([
"loan_amnt",
"int_rate"],ascending=
False)
-
# 升序排列后选择前10
-
df.sort([
"loan_amnt"],ascending=
True).head(
10)
-
# 自定义排序
-
df.sort_values(by=[
'日期',
'类型',
'距离'],ascending=
True,inplace=
True,na_position =
'last')
-
# 索引排序
-
df.sort_index(inplace=
True)
- 27 日期
-
# 设置成日期格式
-
df[
'创建日期'] = pd.to_datetime(data_final[
'创建日期'],format=
'%Y/%m/%d')
-
# 设置为日期索引
-
df.set_index(
'订单提交时间',inplace=
True)
-
-
# 日期索引排序
-
df.sort_index(inplace=
True,ascending=
False)
-
# 日期索引的筛选
-
df_2019 = df[
'2019']
# 日期索引可以直接这样筛选
-
df[
'2019-01']
#按月筛选
-
df[
'2019-03-12':
'2019-03-12']
#筛选某一天数据
-
-
# 改变显示频率(只针对日期索引)
-
df = df.to_period(
'M')
# 针对索引,关键步骤 Q 季度 Y年 D天
-
-
# 计算时间间隔
-
data[
'间隔天数'] = list(map(
lambda x: x.days, pd.to_datetime(
'today') - data[
'生产时间']))
-
df[
'天数'] = df[
'天数'].apply(
lambda x: x.days)
-
-
# 单独表示间隔天数
-
from datetime
import timedelta
-
aDay = timedelta(days=
1)
-
-
# 时间对象格式化
-
df[
'DATE'] = [datetime.strftime(x,
'%Y-%m-%d')
for x
in df[
'DATE']]
-
-
# 时间分组后计算
-
final = data.groupby(data[
'订单时间'].apply(
lambda x: x.strftime(
'%Y%m')))[
'总价'].sum()/
10000
-
data.groupby(data[
'日期'].apply(
lambda x: datetime.strftime(x,
'%Y-%m-%d')))[
'var'].count()
-
data.set_index(
'日期').groupby(
'供应商')[
'数量'].rolling(
'7D').sum().reset_index()
-
final1 = data.groupby([data.to_period(
'Q').index,
'var']).apply(
lambda g: np.average(g[
'var2'], weights=g[
'模次'])).reset_index()
-
-
# 当前时间
-
import time
-
starttime = time.time()
-
-
# 当前日期
-
tim = time.strftime(
"%Y-%m-%d%H%M%S", time.localtime())
-
-
# pd.date_range 时间戳 pd.period_range 时间周期 pd.timedelta_range 时间间隔
-
datelist = pd.date_range(
'2020/11/21', periods=
5)
-
datelist = pd.date_range(
'2020/11/21', periods=
5,freq=
'M')
-
# 生成的数据是每月月初
-
index= pd.date_range(
'2019/02/01', periods=
23,freq=
'MS')
-
pd.date_range(
'2017-01-01 01:00:00',
'2017-01-01 02:00:00', freq=
'5min')
-
-
# 当前日期前3天
-
import pandas
as pd
-
from datetime
import datetime
-
import time
-
lis = pd.date_range(end=
'2021-4-21',periods=
3)
-
str_lis = [datetime.strftime(x,
'%Y-%m-%d')
for x
in lis]
-
lis = pd.date_range(end=time.strftime(
"%Y/%m/%d"),periods=
3)
-
str_lis = [datetime.strftime(x,
'%Y-%m-%d')
for x
in lis]
- 28 判断是否为假期
-
import
datetime
-
import
chinese_calendar
-
demo_time =
datetime.date(2018, 10, 2)
-
# 判断是否是节假日
-
data_is_holiday =
chinese_calendar.is_holiday(demo_time) # True
-
# 判断某日是否工作日
-
data_is_workday =
chinese_calendar.is_workday(demo_time) # False
- 29 数据分组
-
# 方法1
-
data[
'for_m'] = pd.cut(data[
'fortune_x'],[
0,
50,
70,
500],labels = [
'财低',
'财中',
'财高'])
-
# 方法2
-
df = pd.DataFrame({
'value': np.random.randint(
0,
100,
20)})
-
labels = [
"{0} - {1}".format(i, i +
9)
for i in range(0, 100, 10)]
-
df['group'] = pd.cut(df.
value, range(
0,
105,
10), right=False, labels=labels)
- 30 多表合并
-
# 默认纵向连接,产生新的坐标轴
-
df = pd.concat([df1,df2],ignore_index=
True)
-
-
# merge 合并
-
pd.merge(left, right, left_on=
"lkey", right_on=
"rkey",suffixes=(
"_left",
"_right"))
-
pd.merge(df, df, left_on=[
'',
'',
''], right_on=[
'',
'',
''], suffixes=(
'',
''))
-
-
# append 表头一致的多张表,进行连接(上下连接)
-
df1.append(df2).append(df3)
-
-
# combine_first
-
数据填补.有两张表left和right,一般要求它们的表格结构一致,数据量也一致,使用right的数据去填补left的数据缺漏, 如果在同一位置left与right数据不一致,保留left的数据
-
df1.combine_first(df2)
- 31 常用函数
-
count()非空观测数量
-
sum()所有值之和
-
mean()所有值的平均值
-
median()所有值的中位数
-
mode()值的模值
-
std()值的标准偏差
-
var()方差
-
min()所有值中的最小值
-
max()所有值中的最大值
-
abs()绝对值
-
prod()数组元素的乘积
-
cumsum()累计总和
-
cumprod()累计乘积
-
skew()偏斜
-
kurt()峰度
-
quantile()分位数
-
apply()通用申请
-
cov()协方差
-
corr() 相关系数
- 32 描述性统计
-
df.describe(include=[
'object'])
#object - 汇总字符串列 number - 汇总数字列 all - 将所有列汇总在一起(不应将其作为列表值传递)
-
df.describe().round(
2)
# 只保留两位小数
-
df.describe().round(
2).T
#只保留两位小数并转置
-
df.groupby(
'性别').describe().unstack()
-
df.groupby(
'性别')[
'身高'].describe().unstack()
-
df.round(
3)
# 数据可以取消科学计数法?
-
df = df.round(
0)
# 都改为整数
-
# 保留2位小数
-
df[
'a']=df[
'mean'].round(decimals=
2)
-
df[
'b']=df[
'mean'].map(
lambda x:(
"%.2f")%x)
-
df[
'c']=df[
'mean'].map(
lambda x:format(x,
".2%"))
-
description = [data.min(), data.max(), data.mean(), data.std()]
# 依次计算最小值、最大值、均值、标准差
-
description = pd.DataFrame(description, index = [
'Min',
'Max',
'Mean',
'STD']).T
# 将结果存入数据框
-
print(
'描述性统计结果:\n',np.round(description,
2))
- 33 数据预览
-
# 在cmd中安装
-
pip
install pandas-profiling
-
import pandas_profiling
-
pro = pandas_profiling.ProfileReport(data1)
-
pro.to_file(
'output_file.html')
- 34 变化百分比
-
# 元素变化百分比 每个元素与其前一个元素进行比较,并计算变化百分比
-
df.pct
_change()
- 35 协方差
-
# 协方差,
cov用来计算序列对象之间的协方差
-
s1
.cov(
s2)
-
df
['a']
.cov(
df
['b'])
- 36 相关性
-
# 相关性,
pearson(默认),
spearman和
kendall之间的相关性
-
df
['a']
.corr(df[
'b'],method =
'spearman')
-
print (frame.corr())
- 37 排名
-
s.rank() 或者 df.rank()
-
# (axis=0)或列(axis=1)
-
# ascending=True 正向排名或者反向排名
-
# method (average :并列组平均排名,min :组中最低排名,max :组中最高等级,first :按在数组中出现的顺序分配等级)
- 38 分组计算
-
# 多组运算
-
df.groupby([
'班级',
'性别'])[
'身高'].agg([np.sum,np.mean,np.std])
-
df.groupby([
'班级',
'性别']).agg({
'身高':[
'min'],
'体重':[
'max']})
-
df.groupby(
'flee').agg({
'身高': [np.median, np.mean],
'signs': np.mean})
-
df.agg({
'A':np.sum,
'B':np.mean})
# 对不同列进行不同的计算
-
df[[
'A',
'B']].agg([np.sum,np.mean,np.min])
# 对多个变量进行多种计算
-
-
# 时间分组 ,先用pd.to_datetime(字段,格式)将某一列转成日期格式
-
df.groupby(df[
'生日'].apply(
lambda x:x.year)).count()
-
# 分组后选第一个,一般数据先排序
-
df.groupby(df[
'生日'].apply(
lambda x:x.year),as_index=
False).first()
# Tail(n=1) head()
-
# 找到每组中只有一个数据的
-
df.groupby(df[
'生日'].apply(
lambda x:x.month),as_index=
False).filter(
lambda x: len(x)==
1)
-
data2.groupby(
'var').filter(
lambda x:len(x)>=
10)
-
data.groupby(data.index.year)[
'年龄'].mean()
-
-
# 加权平均
-
final3_1 = data_jiep.groupby([
'产业线',
'模号']).apply(
lambda g: np.average(g[
'平均节拍'], weights=g[
'模次'])).reset_index()
-
-
# groupby作图
-
data.groupby(
'race')[
'flee'].value_counts().unstack().plot(kind=
'bar', figsize=(
20,
4))
-
data.groupby(
'flee')[
'age'].plot(kind=
'kde', legend=
True, figsize=(
20,
5))
-
-
# groupby中的几个函数
-
# 累计
-
df.groupby(
'key').aggregate(
'min', np.median, max)
-
# 过滤
-
df.groupby(
'key').filter(某个函数)
-
# 转换
-
df.groupby(
'key').transform(
lambda x: x- x.mean())
-
-
#通过某一个字段分组后,选另一个字段的最小值,构成的数据
-
df = pd.DataFrame({
'AAA': [
1,
1,
1,
2,
2,
2,
3,
3],
'BBB': [
2,
1,
3,
4,
5,
1,
2,
3]})
-
df.loc[df.groupby(
"AAA")[
"BBB"].idxmin()]
-
# 按照一个字段排序,另一个字段分组,选取第一个
-
df.sort_values(by=
"BBB").groupby(
"AAA", as_index=
False).first()
#重新设置索引
-
-
# transform后数据大小不变
-
df[
"Order_Total"] = df.groupby(
'order')[
"ext price"].transform(
'sum')
-
-
result0 = data1.to_period(
'Q').groupby(level=
0).apply(
lambda x :len(x[
'var'].unique().tolist()))
- 39 交叉表
result1 = pd.crosstab(data.index,data['产业线'],margins=True)
- 40 数据透视表
-
df.pivot_table(
'价格',
index=
'产地',columns=
'类别',aggfunc=
'max',margins=True,fill_value=
0,margins_name=
'合计')
-
-
# 用字典形式,可不用values参数
-
df.pivot_table(
index=
'sex', columns=
'class', aggfunc={
'surviced':
'sum',
'fare':
'mean'})
-
-
result = data.pivot_table(
index=data3.to_period(
'M').index,columns=
'是否异常',
values=
'模号', aggfunc=
'count')
-
-
result1 = data.pivot_table(
index=
'var1',columns=data[
'var3'].apply(lambda
x: x.strftime(
'%Y')),
-
aggfunc=
'count',
values=
'var2')
- 41 窗口函数
-
#索引需要为日期 对于明细数据,计算固定大小区域的指标
-
s = pd.Series(np.random.randn(
1000),index=pd.date_range(
'1/1/2000', periods=
1000))
-
s = s.cumsum()
-
r = s.rolling(window=
60)
-
# window:移动窗口的大小
-
# min_periods:需要的非空数据点的阈值(否则结果为NA)
-
# center:布尔值,是否将标签设置在中间(默认为False)
-
-
df[
'数量_re'] = df[
'数量'].rolling(
'7D').sum()
-
-
data1 = data.set_index(
'入库日期').groupby(
'供应商')[
'入库量'].rolling(
'7D').sum().reset_index()
- 42 标准化
-
# 当越小越好时
-
df[
'var_nor'] = (df[
'var'].
max() - df[
'var']) / (df[
'var'].
max() - df[
'var'].
min())
-
# 当越大越好时
-
df[
'var_nor'] = (df[
'var'] - df[
'var'].
min()) / (df[
'var'].
max() - df[
'var'].
min())
-
# 当中值为好是
-
df[
'var'] = np.
abs(df[
'var']-标准值)
-
df[
'var_nor'] = (df[
'var'].
max() - df[
'var']) / (df[
'var'].
max() - df[
'var'].
min())
-
-
# 可以写成通用函数
-
def f2(data,col):
-
col_name = col +
'_nor'
-
data_gp = data.groupby(
'类别').mean()
-
data_gp[col_name] = (data_gp[col] - data_gp[col].
min() ) / (data_gp[col].
max() - data_gp[col].
min() )
-
return data_gp
- 43 去掉异常值
-
def f
2(data,col):
-
q1 = data[col].quantile(q=
0.
25)
-
q3 = data[col].quantile(q=
0.
75)
-
iqr = q
3 - q
1
-
t1 = q
1 -
3*iqr
-
t2 = q
3 +
3*iqr
-
return data[(data[col]>t
1)&(data[col]<t
2)][['类别',col]]
- 44 正太分布和指数分布数据
-
data_norm = pd.DataFrame({
'正太分布':np.random.normal(loc=
60,scale=
15,size=
10000)})
-
data_exp = pd.DataFrame({
'指数分布':np.random.exponential(scale=
15,size=
10000)+
45})
- 45 随机选择
df['strategy'] = np.random.choice([1,2,3],99)
- 46 行列求和
-
# 增加列合计
-
df[
'合计'] = df.sum(axis=
1)
-
# 增加行合计
-
df.loc[
'合计'] = df.sum(axis=
0)
- 47 数据平移
data['经度_前1天'] = data.groupby('var')['经度'].shift(1)
- 48 宽表转窄表
-
test
=
pd.DataFrame(fake_data,
columns=['subject',
'A'
,
'B'
,
'C'
])
-
test
-
subject
A
B
C
-
0
math
88
70
60
-
1
english
90
80
78
-
-
# 转换为窄表
-
pd.melt(test,
id_vars=['subject'])
-
data3
=
pd.melt(data2,
id_vars=['var1','var2'])
-
subject
variable
value
-
0
math
A
88
-
1
english
A
90
-
2
math
B
70
-
3
english
B
80
-
4
math
C
60
-
5
english
C
78
- 49 二维表
df.to_numpy()
- 50 改字典列表
-
df.set_index('ID').T.to_dict('list')
-
{
'p': [
1,
3,
2],
'q': [
4,
3,
2],
'r': [
4,
0,
9]}
- 51 转字典列表
-
datajs =
data.to_json(orient='records',force_ascii=False)
-
# 名称,经度,维度,数值
-
[{
"name":
"虹桥火车站",
"lng":
121.327908,
"lat":
31.20033,
"value":
3.5225437574},{
"name":
"上海火车站",
"lng":
121.46396,
"lat":
31.255155,
"value":
7.0937954904}]
- 52 两列较大值
df['z']=df[['x','y']].max(axis=1)
本人(非计算机专业), 目前在一家500强企业工作, 平常接触数据较多, 每天都需要用到python.
以上内容为工作中总结, 实用性强, 大家可结合自己工作再重新整理, 保存到电脑上随时取用,
顺便说下自己学习python的一些经验:
- 找一本基础书: 有时间就看, 没有时间碰到问题时当参考书用. 比如《利用python进行数据分析》或者《python数据科学手册》;
- 做电子笔记: 书中的功能太多, 而工作常用的并不多, 平时使用或者发现好的用法分类整理成电子笔记. 随用随取;
- 找关联: 将所学内容和工作中的要处理的事情关联;
- 转换输出: 在平台多看一些大牛们整理的资料, 找对自己有用的转换成自己的;
如果对您有帮助, 别忘了关注、点赞哟!
快速掌握以上技巧课程推荐: 链接请点击→
转载:https://blog.csdn.net/muyashui/article/details/116031675
查看评论