LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭
pandas使用基础篇
Youngvan 2022-11-17

一、导入csv文件时,使用pd.read_csv()函数。使用时注意事项如下:

1.文件路径的选择-filepath_or_buffer

2.编码设置- encoding='gbk'

3.表头内容是否跳过不读- skiprows=1

4.只读取多少行的内容-# nrows=15

5.指定某列作为日期格式,否则以字符串类似数据读入-parse_dates=['交易日期']

6.指定某列作为index,否则默认01234等- index_col=['交易日期']

7.读取指定的这几列日期,其他数据不读取。若不指定, 读取全部列-usecols=['交易日期', '收盘价']

8.使用read_csv导入数据非常方便, 导入的数据的数据类型是DataFrame。

二、查看选取数据

===看数据===

# print(df.shape)  # 输出dataframe一共有多少行和多少列

# print(df.shape[0])  # 取行数量,相应的列数量就是df.shape[1]

# print(df.columns)  # 顺序输出每一列的名字,演示如何for语句遍历。

# for col in df.columns:

#     print(col)

# print(df.index)  # 顺序输出每一行的名字,可以for语句遍历。

# for idx in df.index:

#     print(idx)

# print(df.dtypes)  # 数据每一列的类型不一样,比如数字、字符串、日期等。该方法输出每一列变量类型

# print(df.head(3))   # 看前3行的数据,默认是5。与自然语言很接近

# print(df.tail(3))  # 看最后3行的数据,默认是5。

# print(df.sample(frac=0.5))  # 随机抽取3行, 或者用frac(百分之)

# print(df.describe())  # 非常方便的函数,对每一列数据有直观感受;只会对数字类型的列有效

===对print出的数据格式进行修正===

# pd.set_option('expand_frame_repr', False)  # 当列太多时不换行  此代码的位置一般处于刚import结束时

# pd.set_option('max_colwidth', 1)  # 设定每一列的最大宽度

# pd.set_option("display.max_rows", 1000)  # 设定显示最大的行数   None 为显示所有行

# pd.set_option('precision', 1)  # 浮点数的精度

# print(df)

更多设置请见https://pandas.pydata.org/pandas-docs/stable/options.html

===如何选取指定的行和列===

# print(df['开盘价'])   # 根据列名称来选取, 读取的数据是Series类型

# print(df[['交易日期', '收盘价']])  # 同时选取多列, 注意需要两个括号,读取的数据是DataFrame类型

# loc(location)操作: 通过label(columns和index的名字)来读取数据

# 需要关闭parse_dates, 打开index_col

# print(df.loc['1999/11/11'])  # 选取指定的某一行,读取的数据是Series类型

# print(df.loc[['1999/11/11', '1999/11/19']])   # 通过切片选取指定的两行

# print(df.loc['2000/3/30': '2000/4/28'])  # 选取在此范围内的多行,和在list中slice操作类似,读取的数据是DataFrame类型

# print(df.loc[:, '开盘价':'收盘价'])  # 选取在此范围内的多列,读取的数据是DataFrame类型

# print(df.loc['2000/3/30': '2000/7/31', '开盘价': '收盘价'])  # 读取指定的多行、多列。逗号之前是行的范围,逗号之后是列的范围。读取的数据是DataFrame类型

# print(df.at['2000/3/30', '开盘价'])  # # 使用at读取指定的某个元素。loc也行,但是at更高效。

# print(df.loc['2000/3/30', '开盘价'])

以上是我认为最常用的函数

哪里可以看到全部的函数?https://pandas.pydata.org/pandas-docs/stable/api.html


三、列操作

===行列加减乘除===

# print(df['交易日期'] + ' 15:00:00')  # 字符串列可以直接加上字符串,对整列进行操作

# print(df['收盘价'] * 100)  # 数字列直接加上或者乘以数字,对整列进行操作。

# print(df[['收盘价', '成交量']])

# print(df['收盘价'] * df['成交量'])  # 两列之间可以直接操作。收盘价*成交量

===新增一列===

# df['交易日期2'] = df['交易日期'] + ' 00:00:00 '

# print(df)

===统计函数===

# print(df['收盘价'].mean())  # 求一整列的均值,返回一个数,会自动排除空值

# print(df[['收盘价', '成交量']].mean())  # 求两列的均值, 返回两个数, Series

# print(df[['收盘价', '成交量']])

# print(df[['收盘价', '开盘价']].mean(axis=1))  # 求两列的均值, 返回DataFrame。axis=0或者1要搞清楚

# axis=1, 代表对整几列进行操作。axis=0(默认)代表对几行操作。实际中弄混很正常, 到时候试一下就知道了。

# print(df['最高价'].max())  # 最大值

# print(df['最低价'].min())   # 最小值

# print(df['收盘价'].std())    # 标准差

# print(df['收盘价'].count())   # 非空数据的数量

# print(df['收盘价'].median())  # 中位数

# print(df['收盘价'].quantile(0.25))  # 25%分位数

===shift函数、删除列的方式===

# df['下周期收盘价'] = df['收盘价'].shift(-1)  # 读取上一行的数据,若参数设定为3,就是读取上三行的数据;若参数设定为-1,就是读取下一行的数据;

# print(df[['收盘价', '下周期收盘价']])

# del df['下周期收盘价']  # 删除某一列的方法

# df['涨跌'] = df['收盘价'].diff(1)  # 求本行数据和上一行数据相减得到的值, 改为3的话,就是上3行数据相减得到的值, 改为-1的话就是下一行数据相减得到差值

# df.drop(['涨跌'], axis=1, inplace=True)  # 删除某一行的另外一种方式, inplace参数指是否替代原来的df

# df.drop(['涨跌', '收盘价'], axis=1, inplace=True)  # 删除多行数据

# df['涨跌幅'] = df['收盘价'].pct_change(1)  # 类似于diff, 但是求的是两个数直接的比例,相当于求涨跌幅

===cum(cumulative)类函数===

# df['累计成交量'] = df['成交量'].cumsum()  # 该列的累加值

# print(df[['交易日期', '成交量', '累计成交量']])

# df['涨跌幅'] = df['收盘价'].pct_change(1)

# print((df['涨跌幅']+1.0).cumprod())  # 该列的累乘值, 此处计算的就是资金曲线, 假设初始1元钱。

===其他列函数===

# df['收盘价_排名'] = df['收盘价'].rank(ascending=False, pct=False)  # 输出排名。ascending参数代表是顺序还是逆序。pct参数代表输出的是排名还是排名比例

# print(df[['收盘价', '收盘价_排名']])

print(df['收盘价'].value_counts())  # 计数。统计该列中每个元素出现的次数,返回的数据是Series

以上是我认为最常用的函数

哪里可以看到全部的函数?https://pandas.pydata.org/pandas-docs/stable/api.html

四、数据筛选

===根据指定条件,筛选出相关的数据===

# print(df['股票代码'] == 'sh600000')  # 逐行判断交易股票代码是否等于sh600000

# print(df[df['股票代码'] == 'sh600000'])   # 将判断为True的输出:选取股票代码等于sh600000的行

# print(df[df['股票代码'] == 'sh600000'].index)  # 输出判断为True的行的index


"""

df['股票代码'].isin(['sh600000', 'sh600004', 'sz000001'])  判定股票代码在不在我指定的这个list当中

白话说就是先判定股票代码是不是'sh600000', 'sh600004', 'sz000001'

然后把代码放进print(df[])

就成了

print(df[df['股票代码'].isin(['sh600000', 'sh600004', 'sz000001']) ])

"""


# print(df[df['股票代码'].isin(['sh600000', 'sh600004', 'sz000001'])])  # 选取股票代码等于'sh600000'或'sh600004'或'sz000001'的都行

# print(df[df['收盘价'] < 10.0])  # 选取收盘价小于10的行


"""

(df['收盘价'] < 10.0)

(df['股票代码'] == 'sz300641')

(df['收盘价'] < 10.0) & (df['股票代码'] == 'sz300641')

"""


print(df[(df['收盘价'] < 10.0) & (df['股票代码'] == 'sz300641')])  # 两个条件同时成立用&,或者的话就是| 注意此用法仅适用于pandas模块中

print(df[(df['收盘价'] < 10.0) | (df['股票代码'] == 'sz300641')])

注意项:and: 相当于&    or: 相当于|


六、数据整理

===排序函数===

# print(df.sort_values(by=['交易日期'], ascending=0))  # by参数指定按照什么进行排序,acsending参数指定是顺序还是逆序,1顺序,0逆序

# print(df.sort_values(by=['股票代码', '交易日期'], ascending=[0, 0]))  # 按照多列进行排序

两个df上下合并操作,append操作

df1 = df.iloc[0:10][['交易日期', '股票代码', '收盘价', '成交量']]  # 先取0到9行,然后从这10行取出这四列

# print(df1)

df2 = df.iloc[5:15][['交易日期', '股票代码', '收盘价', '成交量']]

# print(df2)

print(df1.append(df2))  # append操作, 将df1和df2上下拼接起来。注意观察拼接之后的index。index可以重复。但是因为会有重复的index,所以需要重新设定index

df3 = df1.append(df2, ignore_index=True)  # ignore_index参数, 用户重新确定index

# print(df3)

===两个df上下合并操作,append操作===

df1 = df.iloc[0:10][['交易日期', '股票代码', '收盘价', '成交量']]  # 先取0到9行,然后从这10行取出这四列

# print(df1)

df2 = df.iloc[5:15][['交易日期', '股票代码', '收盘价', '成交量']]

# print(df2)

print(df1.append(df2))  # append操作, 将df1和df2上下拼接起来。注意观察拼接之后的index。index可以重复。但是因为会有重复的index,所以需要重新设定index

df3 = df1.append(df2, ignore_index=True)  # ignore_index参数, 用户重新确定index

# print(df3)

===对数据去重===

# df3中有重复的行数,我们如何将重复的行数去除?

df3.drop_duplicates(

    subset=['交易日期', '股票代码'],  # subset参数用来指定根据哪类数据来判断是否重复。若不指定,则用全部列的数据来判断是否重复

    keep='first',  # 在去除重复值的时候,我们是保留上面一行还是下面一行?first保留上面一行;last保留下面一行;False就是一旦有两行都重复的话,这两行都不保留

    inplace=True

)

# print(df3)

===其他常用重要函数===

# df.reset_index(inplace=True, drop=False)  # 重置index, drop=False(系统默认为False)等于将原有的index保留并且会形成新的一列留在原始数据中,drop=True就等于将原来index直接去除

# print(df)

# df.rename(columns={'收盘价': 'close',  # rename函数给变量修改名字。使用dict将要修改的名字传给columns参数

                          '开盘价': 'open',

                          '股票代码': 'code',

                          '股票名称': 'name',

                          '交易日期': 'date',

                          '最高价': 'high',

                          '最低价': 'low',

                          '前收盘价': 'prev_close',

                          '成交量': 'volume',

                          '成交额': 'money'

                           }, inplace=True)


print(df.empty)  # 判断一个df是不是为空,此处输出不为空

print(pd.DataFrame().empty)   # pd.DataFrame()创建一个空的DataFrame,此处输出为空

print(df.T)  # 矩阵概念:将数据转置,行变成列,很有用

八、pandas中的时间处理

===时间处理===

print(df['交易日期'])  # 严格意义上说它不是日期格式,而是一个字符串

print(df.at[0, '交易日期'])  # 通过at拿到"交易日期"这一竖列中第一行的数据

print(type(df.at[0, '交易日期']))  # 通过type查看下数据类型  结果显示为类型为str

# pd.to_datetime()  该函数可以将str转化为时间格式的数据类型

# df['交易日期'] = pd.to_datetime(df['交易日期'])  # 将交易日期由字符串改为时间变量

# print(df.at[0, '交易日期'])

# print(type(df.at[0, '交易日期']))  # 结果变成了<class pandas._libs.tslibs.timestamps.Timestamp>

# pd.to_datatime()的强大,看下面几个例子

# print(pd.to_datetime('1999-01-01'))

# print(pd.to_datetime('1999-1-1'))

# print(pd.to_datetime('1999/01/01'))

# print(pd.to_datetime('1999/1/1'))

# print(pd.to_datetime('19990101'))

# print(pd.to_datetime('199911'))    # 唯一一个报错的代码

# print(pd.to_datetime('1999年1月11日'))  # 报错:Unknown string format: 1999年1月11日

# df['交易日期'] = pd.to_datetime(df['交易日期'])

# print(df['交易日期'])

# print(df['交易日期'].dt.day)  # # 输出这个日期的年份。相应的month是月份,day是天数,还有hour, minute, second

# print(df['交易日期'].dt.week)  # dt.week已经提示future warning 要求更换成dt.isocalendar().week

# print(df['交易日期'].dt.isocalendar().week)  # 一年中的第几周

# print(df['交易日期'].dt.dayofyear)  # 这一天是一年当中的第几天

# print(df['交易日期'].dt.dayofweek)  # 这一天是一周当中的第几天,0代表星期一

# print(df['交易日期'].dt.weekday)  # 和上面函数相同,更加常用

# print(df['交易日期'].dt.day_name())  # 和上面函数相同,但返回的是星期几的英文:  weekday_name已经弃用, 改为day_name()

# print(df['交易日期'].dt.days_in_month)  # 这一天所在月份有多少天

# print(df['交易日期'].dt.is_month_start)  # 这一天是否是该月的开头, 是否存在is_month_end?

# print(df['交易日期'].dt.is_month_end)  # 这一天是否是该月的结尾

# print(df['交易日期'] + pd.Timedelta(days=1))  # 增加一天, Timedelta用于表示时间差数据, [weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds]

# print((df['交易日期'] + pd.Timedelta(days=1)) - df['交易日期'])  # 增加一天然后再减去今天的日期

九、滚动操作

===rolling、expanding操作===

# 计算"收盘价"这一列的均值

# print(df['收盘价'].mean())

# print(df['收盘价'])

如何得到每一天的最近3天close的均值呢?即如何计算常用的移动平均线?

===使用rolling函数===

# df['收盘价_3天均值'] = df['收盘价'].rolling(3).mean()

# print(df[['收盘价', '收盘价_3天均值']])

# rolling(n) 即为取最近n行数据的意思,只计算这n行数据. 后面可以接各类计算函数, 例如max, min, std等.

# print(df['收盘价'].rolling(3).max())

# print(df['收盘价'].rolling(3).min())

# print(df['收盘价'].rolling(3).std())

# rolling可以计算每天的最近3天的均值,如果想计算每天的从1开始至今的均值, 应该如何计算?

===使用expanding操作===

# df['收盘价_至今均值'] = df['收盘价'].expanding().mean()

# print(df[['收盘价', '收盘价_至今均值']])

# expanding即为取从头至今的数据.后面可以接各类计算函数

print(df['收盘价'].expanding().max())

print(df['收盘价'].expanding().min())

print(df['收盘价'].expanding().std())

rolling和expanding简直是为量化领域量身定做的方法, 经常会用到。

===输出到本地文件===

df['收盘价_至今均值'] = df['收盘价'].expanding().mean()

print(df)

df.to_csv(r'E:\pycharm projects\new_stock_projects\data\output.csv', encoding='gbk', index=False)  # 存储到csv文件的汉字发生乱码了



推荐文章
评论(0)
分享到
转载我的主页