【无标题】

Pandas的高性能计算:eval()与query()

Numpy与Pandas的底层实际上都是用C语言写成的并为Python预留了接口.

Numpy强大的能力来源于向量化运算和广播功能,而Pandas的强大能力来源于分组型运算

这些抽象的规则在赋予这两大工具强大的处理能力时,却也造成了一个困难:在进行处理时Pandas与Numpy经常会创建临时的中间对象

因此,Pandas从0.13版本(2014年1月发布)开始引入了实验性工具,允许用户直接以C语言速度的来运行程序,并且不需要费力的配置中间数组

即eval()和query()函数,他们都位于Numexpr库中


query()与eval()的设计动机:复合代数式

前面已经介绍过,Pandas和Numpy都支持快速的向量化运算

但是Pandas与Numpy支持的向量化运算的前提就是为所有参与运算的对象显式的分配内存

例如

import numpy

x=np.random.randint(0,10000,10000)
y=np.random.randint(0,10000,10000)
mask=(x > 500) & (y < 500)

Numpy处理上面的程序的步骤是:

  1. 为x和y分配内存并且生成随机数组
  2. 分配中间数组temp_1储存x>500的结果
  3. 分配中间数组temp_2储存y<500的结果
  4. 为mask分配内存并储存temp_1与temp_2与运算的结果

上面的过程一共为x,y,temp_1,temp_2,mask共五个数组分配了大小,最终一共划分了50000个单元内存出去

这在处理大型数据的时候非常的糟糕,所以向量化运算反而会造成程序处理复合代数式时效率的降低

这也就是Numexpr库创立的动机,就是去弥补Numpy的向量化运算在处理复合代数式时的缺陷

Numexpr的思路就是不为中间数组分配内存,即直接取x与y对应位置上的元素进行运算后直接储存到mask中

这样仅需要分配三个数组即可

下面将介绍的Pandas的eval()与query()都是基于Numexpr库实现的

Pandas.eval()实现高性能运算

Pandas的eval()函数用字符串代数式来实现了DataFrame的高性能运算

这里我们使用time模块的clock()函数来计算Python语句的CPU占用时间

DataFrame_1=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_2=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_3=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_4=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))

start_1=time.clock()
DataFrame_1+DataFrame_2+DataFrame_3+DataFrame_4
end_1=time.clock()
print(end_1-start_1)

start_2=time.clock()
pd.eval('DataFrame_1+DataFrame_2+DataFrame_3+DataFrame_4')
end_2=time.clock()
print(end_2-start_2)
>>>
0.07319900000000001
0.02056900000000006

我们可以看到,在处理1000×1000的数组时,使用eval函数就将性能提升了三倍多一点

所以在一般情况下,在处理大型数据时,我们最好使用eval或者query这样的高性能运算来节约运算时间

Pandas.eval()函数支持的运算

在最初的版本,Pandas.eval()函数支持的运算较少,但是从Pandas 0.16版本以后,Pandas.eval()函数就支持许多运算了,下面将一一介绍

算术运算符

Pandas.eval()支持所有的算数运算符,但是依旧需要以字符串的形式给出

DataFrame_1=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_2=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_3=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_4=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))


start_2=time.clock()
pd.eval('(DataFrame_1*DataFrame_2)/(DataFrame_3-DataFrame_4)')
end_2=time.clock()
print(end_2-start_2)
>>>
0.04514499999999999

比较运算符

Pandas.eval()函数支持所有的比较运算符,包括链式代数式

DataFrame_1=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_2=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_3=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_4=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))

start_2=time.clock()
pd.eval('(DataFrame_1<DataFrame_2)&(DataFrame_2<=DataFrame_3)&(DataFrame_3!=DataFrame_4)')
end_2=time.clock()
print(end_2-start_2)
>>>
0.023680999999999952

位运算符

Pandas.eval()函数支持&(按位与)和|(按位或)等位运算

DataFrame_1=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_2=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_3=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_4=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))

start_2=time.clock()
pd.eval('(DataFrame_1<DataFrame_2)|(DataFrame_2>DataFrame_3)&(DataFrame_3==DataFrame_4)')
end_2=time.clock()
print(end_2-start_2)
>>>
0.025263000000000035

此外,Pandas.eval()也支持and,or和not等封装器

对象属性与索引

Pandas.eval()函数也支持在字符串内对DataFrame对象进行索引获取列或者使用索引器来获取值

DataFrame_1=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_2=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_3=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))
DataFrame_4=pd.DataFrame(np.random.randint(0,10000,(1000,1000)))

start_2=time.clock()
ans=pd.eval('DataFrame_2.T[0]==DataFrame_2.iloc[0]')
end_2=time.clock()
print(end_2-start_2)
>>>
0.04004399999999997

但是Pandas.eval()并不支持在索引器中使用切片

其他运算

最后,再说下Pandas.eval()不支持的运算,包括函数调用,条件语句,循环,切片以及更复杂的运算

这些都可以借助Numexpr实现

DataFrame.eval()方法实现列间运算

Pandas.eval()是Pandas的顶层函数,但是DataFrame对象中其实还内置了eval()方法来实现Pandas.eval()支持的所有的运算

使用DataFrame对象的eval()方法的好处就是可以借助列名称直接进行运算

DataFrame_1=pd.DataFrame(np.random.randint(0,10,(3,4)),columns=list('ABCD'),index=list('abc'))
print(DataFrame_1)
start_2=time.clock()
print(DataFrame_1.eval('A+B-C/D'))
end_2=time.clock()
print(end_2-start_2)
>>>
   A  B  C  D
a  9  6  5  4
b  0  0  8  4
c  6  2  6  9
a    13.750000
b    -2.000000
c     7.333333
dtype: float64
0.007834000000000008

使用DataFrame.eval()方法新增列

实际上我们可以在计算的时候使用新的列名,然后指定eval()方法的inplace参数为True

DataFrame_1=pd.DataFrame(np.random.randint(0,10,(3,4)),columns=list('ABCD'),index=list('abc'))
print(DataFrame_1)
start_2=time.clock()
DataFrame_1.eval('E=A+B-C/D',inplace=True)
end_2=time.clock()
print(DataFrame_1)
print(end_2-start_2)
>>>
   A  B  C  D
a  8  0  7  5
b  2  8  9  1
c  5  7  2  0

   A  B  C  D    E
a  8  0  7  5  6.6
b  2  8  9  1  1.0
c  5  7  2  0 -inf
0.007609999999999895

DataFrame.query()方法

基于字符串代数式,DataFrame实现了query()方法,query()方法主要用于链式代数式来实现过滤,即会直接返回符合我们链式代数式的行

DataFrame_1=pd.DataFrame(np.random.randint(0,10,(3,4)),columns=list('ABCD'),index=list('abc'))
print(DataFrame_1)
start_2=time.clock()
print(DataFrame_1.query('A<B'))
end_2=time.clock()
print(end_2-start_2)
>>>
   A  B  C  D
a  6  7  4  9
b  6  6  1  4
c  8  9  3  2
   A  B  C  D
a  6  7  4  9
c  8  9  3  2
0.010602999999999918

性能决定时机

实际上我们到底用不用Pandas.eval(),DataFrame.eval()或者DataFrame.query()的关键在于:计算时间和内存消耗

使用上面的三个函数 / 方法是比直接用Numpy的向量化运算要慢的

当处理小型数据集时,为了追求运算速度,我们可以直接使用Numpy的复合代数式,即便这样会开辟临时数组

急いで!助けて!月経がおかしい - 医師の質疑応答

私は月経が出るたびに、初日は量が少ないですが、粘稠で、流れません。ティッシュペーパーで拭かなければなりません。これは何の原因ですか。どうしよう?附:以前月経に来た时、お腹は痛くありませんでしたが、今はかすかに痛いです。下が膨れて気分が悪い。

輸卵管が太くなる - 医師の質疑応答

病院に行ってみると、卵管が太くなり、太ももの内側に近づくと痛みますが、それほどひどくはありませんが、手で小腹を押すと痛みます。お腹に息があると小腹が痛くなり、便意があるときも痛みます。どうしたの?

今日はどうしたのか分からないが、頭の左後ろが少しあるので、しばらくすると痛いです。 - 医師の質疑応答

先生:今日はどうしたんですか、私の头の左后ろに少しあるんですけど、后でちょっと痛いんです。神経が跳ねたり、痛くなったりして、后で一回、何が原因なのか分からないんですが、お问い合わせしたいんですが、ありがとうございます。それから、痛いところを见つけて、指を押すと痛い感じがします。

私の得たのは唇の疱疹で、どのように治療します - 医師の質疑応答

唇の周りに小さな水疱ができ、元の学校に通っていた頃はたまにいくつかの小さな水疱ができただけで、持続時間が長くなく、かゆみや痛みも感じられなかった(今春の扁桃体手術)。今年出勤して(事务室で)、家を离れても近くて、饮食の问题なのか扁桃体を切って免疫力が下がる问题なのか分からないで、いつも水疱が起きて、それから糜爛して、その上多くの小さい水疱が起きて、かゆくて灼热感があって、特に苦しくて、いつも缲り返し発作して、しかも间隔が非常に短くて1回再発して、私はとても苦痛です。私が得たのはいったいどんな病気なのか、先生は私はとても悩んで今回の発病と持続時間:今度の唇はまた小さい水疱を起こして、すでに2週間の現在の普通の情況:唇の周囲は小さい水疱を起こして、それから糜爛して、かゆみは灼熱感があって、しかも繰り返し発作の病歴があります:喉の両側は少しかわいがって、このような情況は半年余り以前の診断と治療の経過と効果があります:ある医者は私が湿疹だと言って、ある人は私が支原体の多原体の感染だと言って、ある人は私が単純性疱疹だと言って、私はどのように多くの薬を飲んで漢方薬も西洋薬もあって、例えばアシロベイ錠、触ったアシロベイ膏、しかしすべてどん

私は今年24歳で、子供を産んだばかりで2ヶ月近くになりました。帝王切開ですから。 - 医師の質疑応答

私は今年24歳で、ちょうど子供を生んで2ヶ月近くになって、帝王切開のため、尿管を挿して、退院した后に私は阴部が时々かゆいことを発见して、その时私は気にしていませんが、一昨日から小便を発见する时に阴部が痛くて、またかゆくてしかも异臭があって、私は病院に行って検査して“カビ性膣炎”だと言ってしかし私は今ちょうど授乳期で、薬を飲むことができなくて、薬を飲むしかありません。だから、私はどうすればいいですか。今治療は子供に傷害がありますか。

男の人の正常な性交のどれくらいの時間 - 医師の質疑応答

病歴:3年オナニー

腋窩の汗はどのように治療します - 医師の質疑応答

医者こんにちは、私の腋窩の下で汗をかくのはどんな原因が引き起こしたのですか、特に夏の时深刻で、しかし汗をかくのはまた何の異臭もなくて、医者にアドバイスしてもらいます。

膣不規則出血 - 医師の質疑応答

毎月月経がきれいになった後に10日ぐらい膣は暗くて、黒色の血を流して、時に血塊を伴って、普通は3-7日ぐらい持続します。3年くらい経ちましたが、何が原因で、状況が深刻かどうかが待ち遠しいです。今回の発症および持続時間:最後は8月28日の月経浄後10日程度、すなわち9月6日に出血が出現し、10日間持続した。現在の一般的な状況:9月21日に月経が来ていないはずです。本当に心配です。病歴:月経不規則。従来の診断と治療の経過と効果:婦幼病院の医者は月経不規則と診断した。薬を飲んで3ヶ月間調理したが、調理期間中は出血せず、薬を止めてから2ヶ月で出血した。補助検査:B超正常その他:問題補充:出産に影響しますか?今、どんな検査をする必要がありますか?

愚かな女の子は聞く勇気がない。 - 医師の質疑応答

こんにちは性の方面の知識について私の知っているのはとても少なくて、私と私のボーイフレンドが初めて関係が発生する時、どうして私は処女の標識がなくて、私は医者に聞いて、どんな原因のためですか

私の唇はずっと黒くて、冬になるともっと黒くなります。これはどういうことですか。 - 医師の質疑応答

こんにちは。私の唇はずっと黒くて、冬はもっと黒くなりますが、これはどういうことですか?内臓の問題ですか?

私の胃は小さな木の枝が刺さっているような気がします。どうして、どうやって治療しますか。 - 医師の質疑応答

今回の発病及び持続時間:初回病歴:従来の診断と治療経過及び効果なし:補助検査なし:その他なし:なし

「根痛平」は脊椎間盤突出を治療するのに確実な治療効果がありますか? - 医師の質疑応答

「根痛平」は脊椎間盤突出を治療するのに確実な治療効果がありますか?本当に「骨を剃る」ことができて、本当に手術の代わりにすることができますか?一般的にいくつの治療コースで問題を解決できますか?

痔の手術の後でどのようにできるだけ早く回復することができます - 医師の質疑応答

私は1ヶ月前に痔と肛門裂で手術をしましたが、今日は29日になりました。ウンチの時はまだ痛みがあります。椅子に座っても違和感があります。私の手術はずっと塩水でゆとりを持っている。私の状況が正常かどうか分からないが、私はどのようにしてできるだけ早く正常に戻るべきか分からない。専門家の返事を切に待ち望む。

私は女の子がいて、今年4歳になって、3年来いつも扁桃体が炎症を起こします - 医師の質疑応答

私は女の子がいて、今年4歳になって、3年来いつも扁桃体が炎症を起こして、ほとんど毎月病院に行って水を吊っています。何か特効的な方法はありますか?

どのようにしてカルシウムを補うのが好きですか? - 医師の質疑応答

歳半最近娘に微量元素の化学検査をして、腕の採血化学検査で、化学検査の結果カルシウム鉄亜鉛値はすべて正常な範囲内で、しかし私の娘の背と身長はすべて基準に達していないで、比較的にやせて小さくて、医者は血液検査の結果が正確ではないと言って、娘の手首の靭帯は比較的に緩んで、カルシウムが不足して、すぐに1ヶ月のカルシウム鉄亜鉛複合製剤と複合タンパク質亜鉛とビタミンD 3針剤を処方しました。すみません、カルシウム欠乏はどのような方法で検査するのが正確ですか?カルシウム鉄亜鉛複合製剤中のカルシウム鉄亜鉛間の吸収は相互に影響し合いますか?一緒に食べるべきですか?すべてのデザートは禁止されています。ヨーグルトも含まれていますか?(注:検査病院は当市の最も権威のある病院ですが、医者は化学検査やカルシウム補給の諸説に困惑しています)

気分が不安定で、怒りやすくて、いつもいらいらして、この様子は1年余りになりました - 医師の質疑応答

気分が不安定で、怒りやすくて、いつもいらいらして、このように1年余りあって、何の縁因ですか?どうすれば自分の皮気をコントロールできるのか。

2日に1回大便は正常ですか。 - 医師の質疑応答

患者の性別:女性と私の大便はずっとよくなくて、时には2日に1回、时には3日に1回、引き延ばしてもあまり多くありませんが、排便はそんなに難しくなくて、とても悩んで検査を補助します:その他:

高血圧による糖尿病かどうかはわかりませんが - 医師の質疑応答

高血圧低圧はずっと高く、毎日薬を飲んでいるが、効果はあまり明らかではないようだ。よく眠れない、あるいは眠れない。現在の一般的な状況:この1週間の状況はあまりよくなくて、いつもめまいがして、眠れません。先日空腹血糖検査は正常だったが、食後血糖値は少し高かった。糖尿病にかかったかどうか分からない。

ワクチンを打つ時ワクチンとワクチンの間はどのくらい隔てているのが適当です - 医師の質疑応答

:1.ワクチンを打つとき、ワクチンとワクチンの間にどのくらい離れているのがいいですか。2、今月は風邪でワクチンを打っていないので、来月はインフルエンザのワクチンを打って、1月に2種類のワクチンを打つことができますか?3、17ヶ月の赤ちゃんはまず流脳ワクチンを打つべきか、それともインフルエンザワクチンを打つべきか。

なぜ右手の爪に斑点があるのか - 医師の質疑応答

右手の薬指の爪の表面に針の目の大きさの凹みがあり、爪が甲床と分離し始め、爪と肉の間に白いものが広がり、徐々に中に広がり、今では爪の半分しかありません。ビタミンが足りないのではないでしょうか。そして今では右手親指も根元からくぼんだ小さな点が現れ始めています。今回の発病と持続時間:差は3ヶ月もなく、従来の診断と治療の経過と効果:病院に行って外科と皮膚科を見たことがあり、検査を行い、真菌感染はなかった。ビタミン(金施而康)を飲んだことがありますが、効果はありません。

  1. «
  2. 1 ...
  3. 94
  4. 95
  5. 96
  6. 97
  7. 98
  8. 99
  9. 100

ウェブサイトの紹介

Copyright © 2021 Powered by Doctor520.com  ウェブサイトコンテンツの手動レビューとクリーンアップ!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值