from odps import ODPS
from odps.df import DataFrame
o = ODPS(access_id="LTAIBb3aOF3ghjek",
         secret_access_key="FeznNUozVvtEgcpzPUZHIT9vyWyX7W",
         project="satori",
         endpoint="http://service.odps.aliyun.com/api")

girls = DataFrame(o.get_table("girls").get_partition("pt=test"))
'''
关于这里为什么要加上execute,因为我是在pycharm当中执行的
如果用的是ipython,那么可以不用加execute
'''
print(girls.execute()[0:5])
'''
   name  age     anime
0  椎名真白   16  樱花庄的宠物女孩
1  雨宫优子   16      悠久之翼
2  宫村宫子   17      悠久之翼
3  四方茉莉  400      sola
4  森宫苍乃   17      sola
'''

'''
就像pandas一样,给每一个sequence加上一个常量,等于对sequence中的每个元素执行相应的操作
是作用于每一个元素上的
'''
# NULL相关
# 1,isnull,判断是否为空
print(girls.age.isnull().head(5))
'''
     age
0  False
1  False
2  False
3  False
4  False
'''

# 2,notnull,判断是否不为空
print(girls.age.notnull().head(5))
'''
    age
0  True
1  True
2  True
3  True
4  True
'''

# 3,fillna,对位空元素指定缺失值
girls.age.fillna(-1)

# 逻辑判断
# 1,ifelse,条件成立返回第一个,否则返回第二个
print((girls.age >= 20).ifelse("大于20", "小于20").rename("是否大于20").execute())
'''
   是否大于20
0    小于20
1    小于20
2    小于20
3    大于20
4    小于20
5    大于20
6    小于20
7    小于20
8    小于20
9    小于20
10   大于20
11   小于20
12   小于20
13   小于20
14   小于20
'''

# 2,switch,用于多条件判断
print(girls.age.switch(16, "十六", 17, "十七", 18, "十八", default="emmm").rename("是否大于二十").execute())
'''
   是否大于二十
0      十六
1      十六
2      十七
3    emmm
4      十七
5    emmm
6      十八
7      十八
8      十七
9    emmm
10   emmm
11     十七
12     十六
13     十七
14     十六
'''
from odps.df import switch
print(switch(girls.age==16, "十六", girls.age==17, "十七", girls.age==18, "十八", default="emmm").rename("大于20吗?").execute())
'''
  大于20吗?
0      十六
1      十六
2      十七
3    emmm
4      十七
5    emmm
6      十八
7      十八
8      十七
9    emmm
10   emmm
11     十七
12     十六
13     十七
14     十六
'''

# PyODPS 0.7.8 以上版本支持根据条件修改数据集某一列的一部分值,写法为:

girls[girls.age>=20, "anime"] = "大于等于20"
girls[girls.age<20, "anime"] = "小于20"
print(girls.execute())
'''
     name  age   anime
0    椎名真白   16    小于20
1    雨宫优子   16    小于20
2    宫村宫子   17    小于20
3    四方茉莉  400  大于等于20
4    森宫苍乃   17    小于20
5   牧濑红莉栖   20  大于等于20
6   椎名真由理   18    小于20
7    漆原琉华   18    小于20
8    春日野穹   17    小于20
9    坂上智代   19    小于20
10    古河渚   20  大于等于20
11    立华奏   17    小于20
12   和泉纱雾   16    小于20
13    宫园薰   17    小于20
14   秋月爱莉   16    小于20
'''

# 数学运算
'''
对于数字类型的字段,支持+,-,*,/等操作,也支持log、sin等数学计算
'''
print((girls.age * 10).log().sin().rename("乘10求对求正弦").head(5))
'''
   乘10求对求正弦
0 -0.934912
1 -0.934912
2 -0.911693
3  0.904723
4 -0.911693
'''

print(girls[
    girls.age,
    (girls.age / 2).rename("age除以2"),
    (girls.age ** 2).rename("age的2次方")
      ].head(5))
'''
   age  age除以2  age的2次方
0   16     8.0      256
1   16     8.0      256
2   17     8.5      289
3  400   200.0   160000
4   17     8.5      289
'''
'''
算术运算支持的操作包括:
算术操作	    说明
abs	        绝对值
sqrt	    平方根
sin	        正弦
sinh	    双曲正弦函数
cos	        余弦
cosh	    双曲余弦函数
tan	        正切
tanh	    双曲正切函数
arccos	    反余弦
arccosh	    反双曲余弦
arcsin	    反正弦
arcsinh	    反双曲正弦
arctan	    反正切
arctanh	    反双曲正切
exp	        指数函数
expm1	    指数减1
log	        对数
log2	    以2为底
log10	    以10为底
log1p	    log(1+x)
radians	    给定角度计算弧度
degrees	    给定弧度计算角度
ceil	    不小于输入值的最小整数
floor	    向下取整,返回比输入值小的整数值
trunc	    将输入值截取到指定小数点位置
'''

# 对于sequence,也支持和整数的比较
print((girls.age < 20).head(5))
'''
     age
0   True
1   True
2   True
3  False
4   True
'''

# 不支持<=...<=这样的操作,但是支持between
print(girls.age.between(17, 20).head(5))
'''
     age
0  False
1  False
2   True
3  False
4   True
'''

# 默认情况下between是闭区间的,如果开区间需要加上一个参数
print(girls.age.between(17, 20, inclusive=False).head(5))
'''
     age
0  False
1  False
2  False
3  False
4  False
'''

# 上面的操作导致表脏了,所以我将表删除了,又重新建了表

# string相关操作
print(girls[
    girls.name,
    girls.anime.upper().rename("anime_upper"),
      ].head(10))
'''
    name anime_upper
0   椎名真白    樱花庄的宠物女孩
1   雨宫优子        悠久之翼
2   宫村宫子        悠久之翼
3   四方茉莉        SOLA
4   森宫苍乃        SOLA
5  牧濑红莉栖       命运石之门
6  椎名真由理       命运石之门
7   漆原琉华       命运石之门
8   春日野穹         缘之空
9   坂上智代     CLANNAD
'''
'''
string相关操作包括:
capitalize	    大写
contains	    包含某个字符串,如果 regex 参数为 True,则是包含某个正则表达式,默认为 True
count	        指定字符串出现的次数
endswith	    以某个字符串结尾
startswith	    以某个字符串开头
extract	        抽取出某个正则表达式,如果 group 不指定,则返回满足整个 pattern 的子串;否则,返回第几个 group
find	        返回第一次出现的子串位置,若不存在则返回-1
rfind	        从右查找返回子串第一次出现的位置,不存在则返回-1
replace	        将某个 pattern 的子串全部替换成另一个子串, n 参数若指定,则替换n次
get	            返回某个位置上的字符串
len	            返回字符串的长度
ljust	        若未达到指定的 width 的长度,则在右侧填充 fillchar 指定的字符串(默认空格)
rjust	        若未达到指定的 width 的长度,则在左侧填充 fillchar 指定的字符串(默认空格)
lower	        变为全部小写
upper	        变为全部大写
lstrip	        在左侧删除空格(包括空行符)
rstrip	        在右侧删除空格(包括空行符)
strip	        在左右两侧删除空格(包括空行符)
split	        将字符串按分隔符拆分为若干个字符串(返回 list<string> 类型)
pad	            在指定的位置(left,right 或者 both)用指定填充字符(用 fillchar 指定,默认空格)来对齐
repeat	        重复指定 n 次
slice	        切片操作
swapcase	    对调大小写
title	        同 str.title
zfill	        长度没达到指定 width ,则左侧填充0
isalnum	        同 str.isalnum
isalpha	        同 str.isalpha
isdigit	        是否都是数字,同 str.isdigit
isspace	        是否都是空格,同 str.isspace
islower	        是否都是小写,同 str.islower
isupper	        是否都是大写,同 str.isupper
istitle	        同 str.istitle
isnumeric	    同 str.isnumeric
isdecimal	    同 str.isdecimal
todict	        将字符串按分隔符拆分为一个 dict,传入的两个参数分别为项目分隔符和 Key-Value 分隔符
                (返回 dict<string, string> 类型)
strptime	    按格式化读取成时间,时间格式和Python标准库相同
'''

# 时间相关操作
# 这里我们新增一列
import datetime
girls["time"] = datetime.datetime.now()
print(girls[
    girls.time.year.rename("year"),
    girls.time.month.rename("month"),
    girls.time.day.rename("day")
      ].execute())
'''
    year  month  day
0   2018      8   26
1   2018      8   26
2   2018      8   26
3   2018      8   26
4   2018      8   26
5   2018      8   26
6   2018      8   26
7   2018      8   26
8   2018      8   26
9   2018      8   26
10  2018      8   26
11  2018      8   26
12  2018      8   26
13  2018      8   26
14  2018      8   26
15  2018      8   26
16  2018      8   26
'''
'''
与时间相关的属性包括:
时间相关属性	说明
year
month
day
hour
minute
second
weekofyear	返回日期位于那一年的第几周。周一作为一周的第一天
weekday	    返回日期当前周的第几天
dayofweek	同 weekday
strftime	格式化时间,时间格式和 Python 标准库相同
'''

'''
PyODPS 也支持时间的加减操作,比如可以通过以下方法得到前3天的日期。两个日期列相减得到相差的毫秒数。
from odps.df import day
print(girls["time"] - day(3))
支持的时间类型包括:

属性
year
month
day
hour
minute
second
millisecond
'''

# 其他元素操作
# 1,isin查看元素是否在某个集合里
print(girls.age.isin([16, 17, 18]).rename("是否isin").execute())
'''
    是否isin
0     True
1     True
2     True
3    False
4     True
5    False
6     True
7     True
8     True
9    False
10   False
11    True
12    True
13    True
14    True
15   False
16   False
'''

# 2,notin,查看元素是否不在某个集合里
print(girls.age.notin([16, 17, 18]).rename("是否notin").execute())
'''
    是否notin
0     False
1     False
2     False
3      True
4     False
5      True
6     False
7     False
8     False
9      True
10     True
11    False
12    False
13    False
14    False
15     True
16     True
'''

# 3,cut提供离散化的操作,将区间进行划分
# 略

# 使用自定义函数
# DataFrame函数支持对Sequence使用map,它会对它的每个元素调用自定义函数。比如
print(girls.age.map(lambda x: x*10).head(5))
'''
   age
0   160
1   160
2   170
3  4000
4   170
'''

# 如果map之后,sequence的类型发生了变化。需要显式的指定map之后的类型
print(girls.age.map(lambda x: "age"+str(x), "string").head(5))
'''
   age
0   age16
1   age16
2   age17
3  age400
4   age17
'''

# 如果在函数中包含闭包,那么函数外闭包的变量值会引起函数内该变量值的变化,例如:
girls_list = []
for i in range(10):
    girls_list.append(girls.age.map(lambda x: x+i))
# 结果girls_list中每一个SequenceExpr都是girls.age+9
# 因为当循环结束了之后,才会去找i的值,此时i已经指向了9

# 解决的办法就是让一个函数的输出(返回值)来做为另一个函数的输入(参数)
girls_li = []
def get_i(i):
    return lambda x: x+i
for i in range(10):
    girls_li.append(girls.age.map(get_i(i)))
# 此时的i作为参数传进去,那么每一个i值就是传进去的i值
# 类似go语言中的goroutine,写一个循环,当开启多个goroutine,发现打印的都是同一个i值的时候
# 这时候就可以在开启goroutine的时候,将i传进去,否则不传的话,主协程把执行完毕,i指向了最后,
# 那么goroutine在执行的时候都是同一个i值,当然也有可能循环还没结束,goroutine就执行了,
# 但总归不是我们希望的结果

# 当然还有其他办法解决此问题,使用偏函数
from functools import partial
girls_li_ = []
for i in range(10):
    girls_li_.append(girls.age.map(partial(lambda v, x: v+x, i)))

'''
map也支持使用现有的UDF,传入的参数是str类型(函数名),或者function对象
map传入Python函数的实现使用了ODPS Python UDF,则map函数无法使用。除此之外,所有Python UDF的限制在此都适用
关于如何支持Python UDF,可以点击MaxComputer个人主页的头像,点击工单申请,并说明需求然后提交即可,大概从提交工单到开通成功
共需要七个工作日

目前,第三方库(包含C),只能使用numpy,若使用第三方库的话需要把对应的.whl文件上传至MaxComputer。
除了调用自定义函数,DataFrame还提供了很多内置函数,这些函数中一部分使用了map来实现。
因此,如果用户所在project如果没有开通Python UDF,这些函数也就无法使用。
注:阿里云公共服务目前还不提供Python UDF,需要手动提交工单申请

此外:由于字节码的差异,Python3下使用新语言特性(如yield from)时,那么代码在使用Python 2.7的ODPS Worker上执行时会发生错误。
因而建议在 Python 3下使用 MapReduce API 编写生产作业前,先确认相关代码是否能正常执行。
'''

  

6.DataFrame(列运算)的更多相关文章

  1. DataFrame 列运算

    import pandas as pd import StringIO table_buffer = StringIO.StringIO('''a b 2007-01-08 0.786667 270 ...

  2. pandas | DataFrame基础运算以及空值填充

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是pandas数据处理专题的第四篇文章,我们一起来聊聊DataFrame中的索引. 上一篇文章当中我们介绍了DataFrame数据结构当 ...

  3. 雷林鹏分享:jQuery EasyUI 数据网格 - 列运算

    jQuery EasyUI 数据网格 - 列运算 在本教程中,您将学习如何在可编辑的数据网格(datagrid)中包含一个运算的列.一个运算列通常包含一些从一个或多个其他列运算的值. 首先,创建一个可 ...

  4. Java 对字符串数据进行MD5/SHA1哈希散列运算

    Java对字符串数据进行MD5/SHA1哈希散列运算 [java] view plain copy package cn.aibo.test; import java.security.Message ...

  5. Spark DataFrame列的合并与拆分

    版本说明:Spark-2.3.0 使用Spark SQL在对数据进行处理的过程中,可能会遇到对一列数据拆分为多列,或者把多列数据合并为一列.这里记录一下目前想到的对DataFrame列数据进行合并和拆 ...

  6. java 散列运算浅分析 hash()

            文章部分代码图片和总结来自参考资料 哈希和常用的方法 散列,从中文字面意思就很好理解了,分散排列,我们知道数组地址空间连续,查找快,增删慢,而链表,查找慢,增删快,两者结合起来形成散列 ...

  7. 更改DataFrame列顺序

    使用pandas进行数据分析的时候,有时会由于各种需求添加了一些列.可是列的顺序并不能符合自己的期望.这个时候就需要对于列的顺序进行调整. import numpy as np import pand ...

  8. 更改pandas dataframe 列的顺序

    摘自 stackoverflow 这是我的df: Net Upper Lower Mid Zsore Answer option More than once a day 0% 0.22% -0.12 ...

  9. pandas删除dataframe列

    data2 = data.drop(data.columns[0,1,3,4,6,8,10], 1)

随机推荐

  1. Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库

    1.Retrofit+OkHttp的缓存机制 1.1.第一点 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保存缓存数据. 1.2.第二点 ...

  2. 04,Python网络爬虫之requests模块(1)

    引入 Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用. 警告:非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症.冗余代码症.重新发明轮子症.啃文档 ...

  3. Javascript Step by Step - 03

    前言 ajax 即“Asynchronous JavaScript and XML”(异步的JavaScript和XML).现在这个词的覆盖面有所扩展,把允许浏览器与服务器通信而无需刷新当前页面的技术 ...

  4. Javascript Step by Step - 02

    DOM 操作 DOM是面向HTML和XML文档的API,为文档提供了结构化表示.在DOM中一切都是节点Node,文档就是由许多的Node组成的.文档里的每个节点都有属性 nodeName.nodeVa ...

  5. Android stadio 关联源码

    有时候,你想在Android stadio 里看源码, 然后Android stadio 会提示你去下载. 但是下载完了之后,有时候stadio 还是不能看源码.后来,参考这位博客,搞完了. http ...

  6. mybatis 关联查询实现一对多

    场景:最近接到一个项目是查询管理人集合  同时每一个管理人还存在多个出资人   要查询一个管理人列表  每个管理人又包含了出资人列表 采用mybatis关联查询实现返回数据. 实现方式: 1 .在实体 ...

  7. js点击重置按钮重置表单

    <html><head><script type="text/javascript">function formReset(){document ...

  8. 利用Xtrabackup搭建GTID主从复制(一主一从)

      Preface       I've been demonstrated how to implement a master-slave structure using mysqldump in ...

  9. Java基础-3类和对象声明与创建

    一).在1和2中有粗略介绍过类和对象的概念,在这里简单回顾一下: 对象与类:一个实际或者虚拟的物体,这个物体既是我们的对象,这个物体呢又是属于一个分类,如动物类,人类 二).创建对象: 在创建对象的时 ...

  10. 更改maven本地仓库地址

    1.进入maven安装conf文件中,编辑settings.xml文件,新增图中的圈出的内容(我想要存放的地址是D:\HMY\m2\repository) 2.复制settings.xml文件至D:\ ...