python输出字体的⼤⼩_Python之美——⼀只数据狗的笔记[长
期更新]
两年前咬咬⽛跳了Matlab的坑,⼊⼿了Python,从此⼀发不可收的成了PY的重度依赖者。本⼈研究⼯作皆涉及⼤量的数据处理⼯作,PY 和R作为数据分析的两驾马车,得其⼀者得天下。另外,我接触的许多软件皆⽐较⼩众,每次在涉及⼆次开发时,很多都是Matlab之流不⽀持的,⽽PY⼜往往是官⽅指定接⼝。因此,PY作为程序界的黏合剂,实在是⽅便⾄极。
如今机器学习和深度学习之热,再次炒热了PY。当然,涉及到统计模型,R的功⼒还是更深的。很多前沿或者有⼀定深度的统计模型,在R 中都能快速实现,但在PY中则没有现成的package。因此,现在不得不承认,PY和R,各有千秋,要都熟稔才⾏。
写此⽂,是为记录⼀些灵感,供⼴⼤PY爱好者,也供⾃⼰,学习与查阅。
List形式的for in if else
List形式的for in if else
爬到⼀组房价数据,但经纬度皆以'121.43247'的string形式存储于DataFrame的⼀列中,且对于空缺值,以int形式的0或者float⾏驶的0.00填充。也就是说,该列存在多种数据格式,必须写条件判断才能循环。现需要将其进⾏修正提取,将'121.43247'提取为
121.43247,⽽对于空值,统⼀以int形式的0填充。
于是,最低级的写法出现了:
for jj in range(0, len(all_fangjia)):
if all_fangjia.loc[jj, 'len'] > 3:
all_fangjia.loc[jj, 'new_lat'] = all_fangjia.loc[jj, 'lat'].split(''')[1]
all_fangjia.loc[jj, 'new_lon'] = all_fangjia.loc[jj, 'lon'].split(''')[1]
该法思路清晰,但速度奇慢。对该列数据进⾏遍历,先判断该数据长度,如果⼤于3,说明是string形式的,然后再按照'''进⾏拆分(需要⽤来转义),选取第⼆个值进⾏提取。
思路是对的,但速度实在太慢了。于是,就要请出循环的list风格化了:
all_fangjia['new_lon'] = [var.split(''')[1] if len(var) > 3 else 0 for var in all_fangjia['lon']]
all_fangjia['new_lat'] = [var.split(''')[1] if len(var) > 3 else 0 for var in all_fangjia['lat']]
将代码压缩⾄了两⾏,速度更是提升了⼏⼗上百倍(具体提升量级没算,但反正速度是飞快的了)。此法⾮常关键,掌握了对之后的数据处理效率⼤有提升。
佛系空格分隔符的处理
佛系空格分隔符的处理
在拿到某些奇葩的原始数据⽂件时,其不同列间的分隔不是传统的',',⽽是奇葩的不规整的空格符,也
就是说,某两列⽤了三个空格符来分隔,某两列则⽤了四个,甚⾄在⼀列中,某两⾏⽤了2个空格分隔,某两⾏则⽤了3个。。
对于这种佛系空格分隔符,⼀种处理⽅法就是⽤正则(re)表达式,⽽另⼀种⾮常简单的⽅法,则是:
import pandas as pd
ad_csv('583211-2017.out', delim_whitespace=True, engine='python')
即在熊猫包⾥⾯的read_csv中,设置delim_whitespace=True即可。
字符串数据转化为数字编号
python怎么读取txt字符串数据转化为数字编号
⽐如有N个样本,且存在⼀列专门对其类别进⾏标记,但标记⽤的全是字符串,如“⼤”、“中”、“⼩”。为了之后处理⽅便,需要将其变成0、1、2这种数字形式。这时就需要请出category类型来操作了。相关操作皆针对DataFrame格式实现。
obj_df["body_style"] = obj_df[“body_style"].astype('category')
obj_df["body_style_cat"] = obj_df["body_style"].des
绘图时批量改变所有字体⼤⼩
绘图时批量改变所有字体⼤⼩
在利⽤matplotlib绘图时,题⽬、坐标轴标签、坐标轴名称等等的字体⼤⼩都需要分别设置,⾮常⿇烦,⽽下⾯的⽅法则可以批量⼀次性设置,修改起来也就随之⽅便了。
应注意,如果有多个ax,则还需要再嵌套⼀层循环,先指向某⼀个ax.
import matplotlib.pyplot as plt
fig,ax=plt.subplots()
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
<_xticklabels() + ax.get_yticklabels()):
item.set_fontsize(20)
批量快速导⼊Oracle
批量快速导⼊Oracle
做数据⼯作的,拿Python去接数据库是⾮常常见的事情,⽽Oracle⼜是数据库⾥⾯的⽼⼤哥。在此不介绍如何安装接⼝包cx_Oracle,只介绍如何快速将⼤量数据⼀次性导⼊到Oracle中。
在没Get到此技能之前,我都是⼀条条的往⾥⾯插⼊数据的,数据量⼩还好,⼀旦⼤起来,速度就奇慢⽆⽐了。
于是,便有了下⾯的思路:先打包,再导⼊:
import cx_Oracle as oracle
db = t('scott/redhat@192.168.223.138:st')
#对待导⼊的数据进⾏处理
DFV = DFV.fillna('None')
DFV = list()
rows = []
for jj in range(len(DFV)):
# 转list
row = (DFV[jj][0], DFV[jj][1], DFV[jj][2], DFV[jj][3], DFV[jj][4], DFV[jj][5], DFV[jj][6])
rows.append(row)
# 写⼊数据
cr = db.cursor()
cr.prepare(
'insert into OTJ_WATERLINK_WK2 (linkid,fromnode,LONGITUDE,LATITUDE,GRIDID,ROADNAME,SECT) values (:1, :2, :3, :4, :5, :6, :7)')
dbmit()
cr.close()
试过的都知道,速度杠杠的。再也不⽤担⼼⼤型数据⽂件要花上好⼏天才能撸进Oracle了。
Groupby不⽀持的函数如何使⽤
Groupby不⽀持的函数如何使⽤
数据处理⾥⾯的groupby简直就是⼩⽩第⼀课也得学会的技能了。但groupby⽅便虽⽅便,很多时候却不⽀持⼀些函数。⽐如,我要对某⼀列进⾏groupby,并对groupby后的数据块内的另⼀列求分位数。这时:
train_upby([‘TIMEID']).percentile()['GOSPEED']
却显⽰报错,原因是groupby之后的数据块不⽀持percentile()这个函数。
这时你想到的可能就是只能写循环⼀步步进去了,不慌,groupby还给我们留了后路:
upby('TIMEID')
for a,b in dg:
z = np.percentile(b['GOSPEED'],5)
不只是percentile(),其他什么函数,都是可以这么玩的。速度虽然⽐groupby慢了⼀些,但⽐直接写循环进去要快不少。
指定区间,计算频率
指定区间,计算频率
做频率分布直⽅图⼤家都会做,⾮常简单,对离散型变量做频数统计也很简单,value_counts()函数就⾏,但如何对连续型变量按照指定的区间就⾏频率统计呢?这⾥就需要⽤到cut和value_counts()的结合了。
cut函数可以将⼀个区间进⾏切割,返回切割后的⼩块,再将其作为参数传递给value_counts()函数,就可以得出结果了。
xse = range(1, 5000, 1)
fanwei = list(range(0, 4500, 500))
fenzu = pd.cut(xse, fanwei, right=False)
print(fenzu.categories)  # 分组区间,长度8
pinshu = fenzu.value_counts()  # series,区间-个数
读⼊输出⽂件的中⽂乱码问题
读⼊输出⽂件的中⽂乱码问题
这个问题⼤家⼏乎都会遇到,解决⽅法也⾮常简单,只要指定对了编码,⾃然就不会乱码了:
输出CSV乱码的话:
<_csv(‘FINALPOINT.csv',encoding="utf_8_sig",index=False)
导⼊CSV乱码的话:
ad_csv(‘busgps_0309_',encoding='gbk') #gbk不⾏就改成‘gb18030’
不论读⼊导出啥⽂件,记住encoding不要乱,编码就不会乱。
数据结构化输出及读取
数据结构化输出及读取
某个变量需要先保存好,下次再来直接读取,⽽不是重新计算?MATLAB⾥⾯可以直接保存WORKPLACE⾥⾯的变量,PY怎么做呢?⽤pickle
import pickle
#导出
output = open('FWRON.pkl', 'wb')
pickle.dump(FWRON, output, -1)
output.close()
#读取
pkl_file = open('FWRON.pkl', 'rb')
FWRON = pickle.load(pkl_file)
pkl_file.close()
多版本PY的管理
多版本PY的管理
由于不同的包可能在不同版本下才能⽣存,所以⼀台电脑有好⼏个PY很正常,⽽解决他们的共⽣问题也是⼗分的头疼。⽐如我的电脑⾥就有三个版本的PY(我也不知道怎么这么多)。。其中,conda管理的两个:2.7和3.4;还有在系统下的⼀个3.6。
对于⽤conda来管理的各种版本,则可以使⽤conda来进⾏切换,相对要简单很多。切换完毕后,就可以在该版本下进⾏包的安装管理。强烈建议⽤conda⽽⾮pip来安装package。
conda info --envs
source activate python34 # conda activate geo_env
conda install -c conda-forge osmnx
sudo pip install [package_name] --upgrade
⽽我之前没⽤conda之前,⼀直都在⽤系统的3.6。所以,很多时候我还是要对3.6系统下的环境做配置。
下⾯记录了更新pip以及利⽤pip指定版本安装包的过程。注意全程加上python3来指代PY3的版本(我默认是⽤的2.7),以及,记得加上--user,否则会⼀直报错[Errno 13] Permission denied。
curl bootstrap.pypa.io/get-pip.py | python3 - --user
python3 -m pip install  --user osmnx
PY版本是⾮常头疼的事情。最好的办法是完全基于conda来配置⾃⼰的环境。不要和我⼀样,多个PY版本分散在各个地址,配置起来⾮常⿇烦。
⼀⾏代码解决两个字符串组的匹配
⼀⾏代码解决两个字符串组的匹配
近期在做特征的时候,需要对异常站点进⾏清洗。其间遇到⼀个问题,记录如下:
有⼀个list A,⾥⾯存储着系列表征站点错误的关键词,如“关闭”、“不开放”、“⾮运营”。
另外有⼀个list B,⾥⾯存储着所有站点的名称,如“虹桥站”、“上海南站”、“五⾓场站”。
在list B中,有部分站点是出错的,这些站点会在名称中进⾏标记,如虹桥站出错了,该站的名字会改
成“(关闭)虹桥站”,当然,也可能改成“(不开放)虹桥站”。
现在需要把list B中所有的出错站点出来。
问题复述⼀遍就是:以list A中的每⼀个元素为关键词,对list B中每⼀个元素进⾏匹配,如果list B中某个元素包含list A中的任意⼀个元素,则将list B中的该元素标记为FALSE。
当然写循环,⽤ A in B,是肯定可以做的。但是,有没有更简洁的写法呢?
尝试了⼀下,是有的:
Wrong_list=['关闭','不开放','⾮运营']
Test_list=['虹桥站','(不开放)虹桥站']
Bool_result=[any(list(wrongs in var for wrongs in Wrong_list)) for var in Test_list]
最后返回:Bool_result=[FALSE, TRUE]
需要注意:
1)两个for的顺序:先写for wrongs in Wrong_list,再写for var in Test_list,最终得出的Bool_result才是针对Test_list的。
2)list在此的作⽤:将generator object 转化为bool格式。
3)any在此的作⽤:表⽰“只要有⼀即可”。
4)括号在此的作⽤:为any提供计算优先级。
applymap与匿名函数
applymap与匿名函数
常常会遇到需要对矩阵中的所有数值执⾏某个函数的情况,但⼜懒得写def,这时候就可以祭出applymap⼤杀器了:
DF.applymap(lambda x: -(x * math.log(x)) if x > 0 else np.nan)
这句话的功能是,对DF这个矩阵⾥⾯的每⼀个⼤于0的值,执⾏-(x * math.log(x))的运算,如果该值⼩于0,则置为nan。
要注意applymap和apply的区别。后者是对⾏或列进⾏处理:
DF.apply(lambda x: sum(x != 0), axis=1)
如上⾯的代码,则是返回每⼀⾏(axis=1)中不等于0的个数。
去除DF中含有重复名字的列
去除DF中含有重复名字的列
有时候MERGE多了,难免会出现⼀个DF⾥⾯有好⼀些列完全⼀致——内容⼀致,列名也⼀致。这在某些时候,列名⼀致是容易出错的,最好需要及时清理他们。清理⽅法是:
DF=DF.ix[:,~DF.columns.duplicated()]
⼀句话就可以去重啦,⾮常的利索有没有。
选取groupby后某列最⼩值对应的⾏
选取groupby后某列最⼩值对应的⾏
做数据处理的时候常常会遇到这样的问题:对于⼀个DF,我们按照A、B两列进⾏groupby后,选取每个group内C列最⼩值所对应的⾏并返回。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。