apply也是可以计算列的,但更重要的功能是按行计算和groupby联合使用。
但是我一直都没太搞懂这个apply,今天查了一下发现几个问题。
比如我想把股票的最高涨幅和最低涨幅算出来。
用tushare获取随便一只股票的一段时间的数据。
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()
得到初始数据。
这里我就随便找了一只。数据如下,因为涨幅都是(今日最高价/昨日收盘价-1)*100
昨日收盘价用shift向下滑一格比较方便。然后初始数据就是这样了。
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
对于今天的问题最简单的方法还是直接列计算。
gf['high_rate'] = (gf['high']/gf['qclose'] - 1) * 100
gf['low_rate'] = (gf['low'] / gf['qclose'] - 1) * 100
但是今天研究的是apply。就用apply试试。行元素axis=1,我想应该把dataframe变成跟参数一样多个数吧。
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)
哈哈,果然报错。
然后我用了这个网址的方法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)
我觉得这是脱了裤子放屁啊,完全不懂为啥这么干,能用列计算的写这个def的价值何在?我可能需要单独一个元素然后去获得其他资源跟一列有啥关系?
查了查stackoverflow发现问题了。
多列apply问题
axis=1
如果def的参数f(x)x只是普通参数,比如str,float之类。这好像会默认按行计算,而不是按我想的是行元素。
行元素的话,要把参数变成dataframe才行。
如这篇文章第二个例子
df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1)还是不太对,我想还是用回map吧。
最后apply应该是用于groupby比较多吧,但是groupby之后还是按列计算的比较多吧,applymap是对于一个dataframe中每一个元素进行计算,我觉得也不太好用,因为列都是各种特征要统一计算的话,我能想到的是normalize,这个用sklearn有专门的模块,好用。
失败的apply运用,有点没想到什么时候必须用到它。
然后又不死心,又搜索一番,发现了第二个方法。方法二
看起来好像要把dataframe切片之后才能用到元素级别。结果还是这样啊,
看起来还是一行为一个参数,看起来apply运用在多列上计算还是不太理想。