我的Pandas应用场景(2)
上文交代了一些啰嗦事,本文开始,就要来点实际的了。
先来一个比较简单的场景:
Given:一个包括N(极其复杂,这里取3个)个列的DataFrame:df,df包括index;
And:对df所有列元素进行一些处理,得到df的一个变换后的df_new;
And:对df_new的某些列做极其复杂的判断,得到新的列result;
When:需要将要根据result对df进行分析;
Then:将result追加到df中。
上述的场景是我的一个算法验证的场景,简单地说,就是需要通过对原始数据进行变换,然后得到新的列,然后追加到原始数据中,最后进行分析。
首先构造一下模拟的数据吧。我们的数据通过随机数产生,为10*3的数据,每一列的名称为A/B/C,放到csv格式的文件中,文件内容如下所示:
A,B,C
4.556325895482557,4.9467487190814206,9.240498646959768
6.798122785026925,9.205498509979439,6.495701755638054
1.7088666262153485,1.9490481646738644,5.016719349132167
7.68793618140002,4.288529993589748,0.4479283787649413
0.22238136867848257,2.861119654701667,5.296500633944277
3.8352546975711,0.29287579880826087,1.0438719791356377
4.603712955967749,5.647815101448938,0.6054047619225811
6.916870514198006,8.903690009637602,4.836793019361064
9.845396552800361,0.8159084013183737,0.8425827491512894
2.425545747141858,7.353661205806686,2.982326067390466
一般字符型的文件会以上述的逗号隔开的方式存储,通过pandas的read_csv()可以方便的读入数据到DataFrame,如下代码所示:
import pandas as pd
import numpy as np df = pd.read_csv('d:/data.csv')
pd.read_csv()默认的读法就是上述代码那样,他会将第一行当做列名读入。假如我们的csv数据中不包含列名,可以通过header=None来禁止将第一行当做列名;假如csv数据中没有列名,而我们想要指定列名,这也是我经常做的,可以通过name=[]参数,通过一个列表指定所有列的名称。指定列名有一个好处就是列名可以当做DataFrame的属性,对列进行访问,后续会介绍。
读进来的输入如下所示:

然后,我们需要对df进行变换。
这里模拟一种变换,就是将每一列进行均值位0,方差为1的变换,代码如下:
import pandas as pd
import numpy as np df = pd.read_csv('d:/data.csv') df_new = df.apply(lambda col: (col - col.mean()) * 1.0 / col.std())
df_new
其中,df.apply()函数是df的一个函数式接口,表示依次对df的列(A/B/C)进行迭代,其参数为一个lambda表达式,lambda的参数col就表示df的一个列。
col其实是Series的一个对象,其中包含大量的数据处理方法,这里实用的是其中两个:均值mean()和std()方差。
lambda的实现部分使用了Pandas的向量化的运算方式,也就是说col虽然是一个Series,但是我们对其操作就像操作一个标量一样,但是自动传播给所有的元素。
经过上述代码的运算,每一列都被映射到新的df_new中,这个方式在机器学习、数据挖掘中很常见。结果如下图所示。
| A | B | C | |
|---|---|---|---|
| 0 | -0.102247 | 0.100417 | 1.865099 |
| 1 | 0.652462 | 1.435738 | 0.944303 |
| 2 | -1.060854 | -0.839506 | 0.448149 |
| 3 | 0.952021 | -0.105966 | -1.084541 |
| 4 | -1.561285 | -0.553528 | 0.542008 |
| 5 | -0.344998 | -1.358795 | -0.884620 |
| 6 | -0.086294 | 0.320234 | -1.031713 |
| 7 | 0.692439 | 1.341107 | 0.387790 |
| 8 | 1.678338 | -1.194799 | -0.952147 |
| 9 | -0.819582 | 0.855099 | -0.234328 |
现在,我们要使用df_new的数据计算我们的结果了。如果逻辑很简单,则可以直接通过Pandas的IF THEN逻辑实现,复杂的算法可以需要自己一行一行的遍历df_new,通过if else逻辑实现。我们先说一个简单的情况。
假如,我们的算法是这样的:如果A>0.5并且B<0.5,则为True,否则如果C>0.5,则为True,则否为False,实现代码如下所示:
import pandas as pd
import numpy as np df = pd.read_csv('d:/data.csv') df_new = df.apply(lambda col: (col - col.mean()) * 1.0 / col.std()) df_new.ix[(df_new.A > 0.5) & (df_new.B < 0.5), 'Result'] = True
df_new.ix[~((df_new.A > 0.5) & (df_new.B < 0.5)) & (df_new.C > 0.5), 'Result'] = True
df_new.ix[~(~((df_new.A > 0.5) & (df_new.B < 0.5)) & (df_new.C > 0.5)), 'Result'] = False
df_new
结果如下所示:
| A | B | C | Result | |
|---|---|---|---|---|
| 0 | -0.102247 | 0.100417 | 1.865099 | True |
| 1 | 0.652462 | 1.435738 | 0.944303 | True |
| 2 | -1.060854 | -0.839506 | 0.448149 | False |
| 3 | 0.952021 | -0.105966 | -1.084541 | False |
| 4 | -1.561285 | -0.553528 | 0.542008 | True |
| 5 | -0.344998 | -1.358795 | -0.884620 | False |
| 6 | -0.086294 | 0.320234 | -1.031713 | False |
| 7 | 0.692439 | 1.341107 | 0.387790 | False |
| 8 | 1.678338 | -1.194799 | -0.952147 | False |
| 9 | -0.819582 | 0.855099 | -0.234328 | False |
由于算法逻辑不是很复杂,抽象起来也就三个情况,所以通过Pandas的IF Then的机制实现了Result列的添加。
DataFrame.ix[condition, 'newOrExistsColname'] = value,具体可以参考Pandas的十分钟入门教程,开始就是讲这个的。
需要强调的是我们通过df_new.A这样的方式访问A列元素,这是Pandas的方便之处;并且各种比较和& ~操作都是针对元素的;并且只有index相同的元素才会比较,而且Result也是添加到对应的index列的。
假如算法实现在太复杂,不是简单的集中情况可以讲清楚的,这个时候我采用的方法就是C++和Java中最常使用的for循环了,几乎万能。还以上述的算法为例,代码如下:
import pandas as pd
import numpy as np df = pd.read_csv('d:/data.csv') df_new = df.apply(lambda col: (col - col.mean()) * 1.0 / col.std()) result = pd.Series([False]*len(df_new))
for i in range(len(df_new)):
item = df_new.iloc[i, :]
if item.A > 0.5 and item.B < 0.5:
result[i] = True
elif item.C > 0.5:
result[i] = True
else:
result[i] = False # unnecessary
df_new['Result'] = result
df_new
代码中一片浓郁的C、Java风格,虽然不那么函数式也不向量化,但是我就是感觉熟悉,毕竟我最早学习的是C。
首先,我定义了一个Series,初始化为False,然后通过一个for循环,遍历df_new的所有行,依次为result赋值,最后,通过df_new['newcolname']=的方式将resut追加到df_new中了。
注意,当将Series往DataFrame或者Series中拼接的时候,默认的都是安装index对齐的,也就是行的index一致的才会拼接到一起,而与行的顺序无关,这点是Pandas的强大之处(数据的自动对齐,在groupby之后的数据中特别有用),千万别忽视了这点。
最后,我们要将df_new.Result追加给df,因为df_new.Result本质上还是一个Series,所以上述的代码中已经有了一种方式:df.ix['Result']=df_new.Result。
代码如下:
import pandas as pd
import numpy as np df = pd.read_csv('d:/data.csv') df_new = df.apply(lambda col: (col - col.mean()) * 1.0 / col.std()) result = pd.Series([False]*len(df_new))
for i in range(len(df_new)):
item = df_new.iloc[i, :]
if item.A > 0.5 and item.B < 0.5:
result[i] = True
elif item.C > 0.5:
result[i] = True
else:
result[i] = False # unnecessary
df_new['Result'] = result
df['Result'] = df_new.Result
df
最终结果如下:
| A | B | C | Result | |
|---|---|---|---|---|
| 0 | 4.556326 | 4.946749 | 9.240499 | True |
| 1 | 6.798123 | 9.205499 | 6.495702 | True |
| 2 | 1.708867 | 1.949048 | 5.016719 | False |
| 3 | 7.687936 | 4.288530 | 0.447928 | True |
| 4 | 0.222381 | 2.861120 | 5.296501 | True |
| 5 | 3.835255 | 0.292876 | 1.043872 | False |
| 6 | 4.603713 | 5.647815 | 0.605405 | False |
| 7 | 6.916871 | 8.903690 | 4.836793 | False |
| 8 | 9.845397 | 0.815908 | 0.842583 | True |
| 9 | 2.425546 | 7.353661 | 2.982326 | False |
本文要点:
Pandas读取CSV文件方法;
Pandas的追加新列方法:df.ix[condition, 'newcolname'] = value(标量或者向量) 或者 df['newcolname'] = value(标量或者向量);
Pandas的df.apply()对列进行迭代的方法;
Pandas的df中的一些常用的数据处理方法;
Pandas的Series的简单逻辑操作& | ~;
看,是不是很简单。
未完待续……
我的Pandas应用场景(2)的更多相关文章
- 我的Pandas应用场景
声明 工作后,很不幸的成为了团队中的QA.QA这个角色吧,说起来高大上,实际很苦逼,一句话概括一下:吃力不讨好!作为新人,公司每月一分钱没少我,至少现在跟开发的待遇是一样的,所以我还是得兢兢业业的对待 ...
- pandas中df.ix, df.loc, df.iloc 的使用场景以及区别
pandas中df.ix, df.loc, df.iloc 的使用场景以及区别: https://stackoverflow.com/questions/31593201/pandas-iloc-vs ...
- 整理pandas操作
本文原创,转载请标识出处: http://www.cnblogs.com/xiaoxuebiye/p/7223774.html 导入数据: pd.read_csv(filename):从CSV文件导入 ...
- 深入理解pandas读取excel,txt,csv文件等命令
pandas读取文件官方提供的文档 在使用pandas读取文件之前,必备的内容,必然属于官方文档,官方文档查阅地址 http://pandas.pydata.org/pandas-docs/versi ...
- Pandas模块
前言: 最近公司有数据分析的任务,如果使用Python做数据分析,那么对Pandas模块的学习是必不可少的: 本篇文章基于Pandas 0.20.0版本 话不多说社会你根哥!开干! pip insta ...
- numpy、pandas
numpy: 仨属性:ndim-维度个数:shape-维度大小:dtype-数据类型. numpy和pandas各def的axis缺省为0,作用于列,除DataFrame的.sort_index()和 ...
- 借网站日记分析~普及一下Pandas基础
对网站日记分析其实比较常见,今天模拟演示一下一些应用场景,也顺便说说Pandas,图示部分也简单分析了下 1.数据清洗¶ 一般数据都不可能直接拿来用的,或多或少都得清理一下,我这边就模拟一下清洗完 ...
- pandas中遍历dataframe的每一个元素
假如有一个需求场景需要遍历一个csv或excel中的每一个元素,判断这个元素是否含有某个关键字 那么可以用python的pandas库来实现. 方法一: pandas的dataframe有一个很好用的 ...
- pandas处理时间序列(2):DatetimeIndex、索引和选择、含有重复索引的时间序列、日期范围与频率和移位、时间区间和区间算术
一.时间序列基础 1. 时间戳索引DatetimeIndex 生成20个DatetimeIndex from datetime import datetime dates = pd.date_rang ...
随机推荐
- Duanxx的STM32学习:NVIC操作
版权声明:本文博客原创文章,博客,未经同意,不得转载.
- hbase ganglia监控配置
hbase ganglia 显示器 hbase 构造 hadoop-metrics2-hbase.properties *.sink.ganglia.class=org.apache.hadoop.m ...
- C++程序中应增加STL、运算和字符串的头文件
#include <complex> //模板类complex的标准头文件 #include <valarray> //模板类valarray的标准头文件 #include & ...
- PL/SQL联系oracle成功可以sql解决的办法是检查表的名称无法显示
有时,因为机器突然断电或其他原因PL/SQL它甚至不能在数据库表后显示.序列和其它元素.使用SQL Windows运行查询一般查询,登录或同样的现象再次. 我是不是可以解决因重复登录的猜测是,PLSQ ...
- CreateMutex
C++ API CreateMutex 找出当前系统是否已经存在指定进程的实例.假设没有则创建一个相互排斥体.CreateMutex()函数可用来创建一个有名或无名的相互排斥量对象. HANDLE C ...
- HTML5 五彩圆环Loading加载动画实现教程
原文:HTML5 五彩圆环Loading加载动画实现教程 今天我们要来介绍一款效果很特别的HTML5 Loading加载动画,不像其他的Loading动画,这款Loading动画颜色很丰富,并且在转圈 ...
- shell 批量压缩指定文件夹及子文件夹内图片
shell 批量压缩指定文件夹及子文件夹内图片 用户上传的图片,一般都没有经过压缩,造成空间浪费.因此须要编写一个程序,查找文件夹及子文件夹的图片文件(jpg,gif,png),将大于某值的图片进行压 ...
- 工作流设计参考(包括PHP实现)
工作流很少有让人满意的,即便是国内用的比较多的jbpm,用起来也会觉得很便扭.再加上PHP中没有什么好用的工作流,于是干脆自己设计一个,设计的原则如下: 1 根据80/20原则,只使用wfmc模型中最 ...
- 【hoj】2651 pie 二分查找
二分查找是一个非常主要的算法,针对的是有序的数列,通过中间值的大小来推断接下来查找的是左半段还是右半段,直到中间值的大小等于要找到的数时或者中间值满足一定的条件就返回,所以当有些问题要求在一定范围内找 ...
- c#开发之多国语言解决方案gnu.gettext + poedit
1.工具简介 1.1.关于i18n i18n其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数是“国际化”的简称. i10n为资源本地化,全称为Locali ...