首页 📚生活杂谈

pandas数据分析处理52个常用技巧

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 f2(data,col):
    q1 = data[col].quantile(q=0.25)     
    q3 = data[col].quantile(q=0.75)
    iqr = q3 - q1
    t1 = q1 - 3*iqr
    t2 = q3 + 3*iqr
    return data[(data[col]>t1)&(data[col]<t2)][['类别',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)


文章评论

目录