apply也是可以計(jì)算列的,但更重要的功能是按行計(jì)算和groupby聯(lián)合使用。
但是我一直都沒太搞懂這個apply,今天查了一下發(fā)現(xiàn)幾個問題。
比如我想把股票的最高漲幅和最低漲幅算出來。
用tushare獲取隨便一只股票的一段時間的數(shù)據(jù)。
import pandas as pd
import tushare as ts
gf = ts.get_k_data('601888', start='2017-08-09', end='2017-08-23')
gf = gf.reset_index(drop=True)
gf['qclose'] = gf['close'].shift()
得到初始數(shù)據(jù)。
這里我就隨便找了一只。數(shù)據(jù)如下,因?yàn)闈q幅都是(今日最高價/昨日收盤價-1)*100
昨日收盤價用shift向下滑一格比較方便。然后初始數(shù)據(jù)就是這樣了。
date open close high low volume code qclose
0 2017-08-09 28.19 28.50 28.56 28.02 67591.0 601888 NaN
1 2017-08-10 28.38 28.19 28.72 28.10 64321.0 601888 28.50
2 2017-08-11 28.16 27.85 28.37 27.77 59756.0 601888 28.19
3 2017-08-14 27.84 28.00 28.38 27.81 67315.0 601888 27.85
4 2017-08-15 28.18 27.97 28.18 27.89 52820.0 601888 28.00
5 2017-08-16 27.95 28.41 28.56 27.95 60186.0 601888 27.97
6 2017-08-17 28.41 28.82 28.89 28.41 49456.0 601888 28.41
7 2017-08-18 28.70 29.40 29.46 28.62 106633.0 601888 28.82
8 2017-08-21 29.30 29.76 30.20 29.29 129638.0 601888 29.40
9 2017-08-22 29.76 29.59 30.06 29.30 79633.0 601888 29.76
10 2017-08-23 29.59 29.48 30.25 29.40 80800.0 601888 29.59
對于今天的問題最簡單的方法還是直接列計(jì)算。
gf['high_rate'] = (gf['high']/gf['qclose'] - 1) * 100
gf['low_rate'] = (gf['low'] / gf['qclose'] - 1) * 100
但是今天研究的是apply。就用apply試試。行元素axis=1,我想應(yīng)該把dataframe變成跟參數(shù)一樣多個數(shù)吧。
def rate(qclose,high,low):
high_rate = (high / qclose - 1) * 100
low_rate = (low / qclose - 1) * 100
return high_rate,low_rate
gf = gf[['high', 'low','qclose']]
gf.apply(rate,axis=1)
哈哈,果然報錯。

然后我用了這個網(wǎng)址的方法pandas中apply的使用方法
def rate(gf):
gf['high_rate'] = (gf['high'] / gf['qclose'] - 1) * 100
gf['low_rate'] = (gf['low'] / gf['qclose'] - 1) * 100
return gf
gf = gf[['high', 'low','qclose']]
df = gf.apply(rate,axis =1)
# print(gf)
print(df)
我覺得這是脫了褲子放屁啊,完全不懂為啥這么干,能用列計(jì)算的寫這個def的價值何在?我可能需要單獨(dú)一個元素然后去獲得其他資源跟一列有啥關(guān)系?
查了查stackoverflow發(fā)現(xiàn)問題了。
多列apply問題
axis=1
如果def的參數(shù)f(x)x只是普通參數(shù),比如str,float之類。這好像會默認(rèn)按行計(jì)算,而不是按我想的是行元素。
行元素的話,要把參數(shù)變成dataframe才行。
如這篇文章第二個例子
df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1)還是不太對,我想還是用回map吧。
最后apply應(yīng)該是用于groupby比較多吧,但是groupby之后還是按列計(jì)算的比較多吧,applymap是對于一個dataframe中每一個元素進(jìn)行計(jì)算,我覺得也不太好用,因?yàn)榱卸际歉鞣N特征要統(tǒng)一計(jì)算的話,我能想到的是normalize,這個用sklearn有專門的模塊,好用。
失敗的apply運(yùn)用,有點(diǎn)沒想到什么時候必須用到它。
然后又不死心,又搜索一番,發(fā)現(xiàn)了第二個方法。方法二
看起來好像要把dataframe切片之后才能用到元素級別。結(jié)果還是這樣啊,

看起來還是一行為一個參數(shù),看起來apply運(yùn)用在多列上計(jì)算還是不太理想。