首先导入pandas模块
import pandas as pd
1.Series数据结构
(1)利用列表创建
s1 = pd.Series(['a', 'b', 'c', 'd'])
s1
运行结果:
0 a
1 b
2 c
3 d
dtype: object
指定索引
s2 = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
s2
运行结果:
a 1
b 2
c 3
d 4
dtype: int64
(2)利用字典创建
s3 = pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4})
s3
运行结果:
a 1
b 2
c 3
d 4
dtype: int64
(3) 利用index方法获取Series的索引
s1.index
运行结果:RangeIndex(start=0, stop=4, step=1)
(4)利用values方法获取Series的值
s1.values
运行结果:array(['a', 'b', 'c', 'd'], dtype=object)
2.DataFrame表格型数据结构
df1 = pd.DataFrame(['a', 'b', 'c', 'd'])
df1
运行结果:
0
0 a
1 b
2 c
3 d
df2 = pd.DataFrame(np.array([['a', 'A'], ['b', 'B'], ['c', 'C'], ['d', 'D']]))
df2
运行结果:
0 1
0 a A
1 b B
2 c C
3 d D
df2 = pd.DataFrame(np.array([['a', 'A'], ['b', 'B'], ['c', 'C'], ['d', 'D']]),
columns = ['lowercase', 'uppercase'],
index = ['一', '二', '三', '四'])
df2
运行结果:
lowercase uppercase
一 a A
二 b B
三 c C
四 d D
3.用pandas读取数据
(1) 用pd.read_table()读取
df1 = pd.read_table(r"data\pe_ttm.txt")
df1
运行结果:
000001.SZ 8.86955738067627
0 000002.SZ 10.041342
1 000004.SZ 159.500244
2 000005.SZ 104.869804
3 000006.SZ 10.294246
4 000007.SZ -990.868042
... ... ...
3594 603993.SH 21.713005
3595 603996.SH 20.441048
3596 603997.SH 21.779991
3597 603998.SH 64.759041
3598 603999.SH 68.323235
3599 rows × 2 columns
(2)读取excel文件
df2 = pd.read_excel(r"data\行业指数.xlsx", skiprows=1)#skiprows跳过第一行
df2
(3)读取csv文件
df3 = pd.read_csv(r"data/行业指数pe_ttm.CSV", engine='python',skiprows=1,encoding='gbk')
df3
(4)查看数据类型 .info()
(5)获取数值分布情况 .describe()方法
4.数据预处理
(1)缺失值处理:查看、删除、填充
# 缺失值处理
df = pd.DataFrame({'编号': ['A1', 'A2', np.nan, 'A4'], '年龄': [54, 16, np.nan, 41],
'性别': ['男', np.nan, np.nan, '男'],
'注册时间': ['2018/8/8', '2018/8/9', 'np.nan', '2018/8/11']})
df.info() # 查看数据情况
df.isnull() # 返回布尔值查看缺失值位置
df.dropna(how='all') # 删除缺失值的行
df.fillna(0) # 缺失值用0填充
df.fillna({'编号':'A', '性别':'男','年龄':'40','注册时间':'2018/8/10'})#有选择的填充
df.fillna({}) # 传入字典针对性填充,字典的key为列名,value为缺失值填充的内容
这些操作都不会改变df,可以使用新赋值的方法改变df
(2)重复值处理
df = pd.DataFrame({'order': ['A1', 'A2', 'A3', 'A3', 'A4', 'A5'],
'name': ['Alice', 'Bob', 'Jack', 'Jack', 'Luna', 'Luna'],
'code': [101, 102, 103, 103, 104, 104],
'date': ['2018-08-08', '2018-08-09', '2018-08-10', '2018-08-10',
'2018-08-11', '2018-08-12']})
df
运行结果:
order name code date
0 A1 Alice 101 2018-08-08
1 A2 Bob 102 2018-08-09
2 A3 Jack 103 2018-08-10
3 A3 Jack 103 2018-08-10
4 A4 Luna 104 2018-08-11
5 A5 Luna 104 2018-08-12
df.drop_duplicates() # 默认对每一列重复值进行判断并删除重复值
运行结果:
order name code date
0 A1 Alice 101 2018-08-08
1 A2 Bob 102 2018-08-09
2 A3 Jack 103 2018-08-10
4 A4 Luna 104 2018-08-11
5 A5 Luna 104 2018-08-12
(3)异常值处理:异常值检测、异常值替换
df.drop_duplicates(subset=['order'],keep='last')
数据类型转换
df['order'].dtype
df['code'].dtype
df['code'].astype('float64')
(4)索引设置
重新指定某列作为新的索引 .set_index(列名称)
df3 = pd.read_csv(r"data/行业指数pe_ttm.CSV", engine='python', skiprows=1,encoding='gbk')
df3.set_index('时间')
层次化索引
df4 = pd.DataFrame({'code': [1, 2, 2, 4, 5, 5, 6],
'name': ['a', 'a', 'b', 'c', 'd', 'd', 'e'],
'value':[12, 14, 17, 20, 25, 26, 30]})
df4.set_index(['code', 'name'])
重命名索引
df4
df4.rename(columns={'code': 'new_code', 'name': 'new_name'}) # 重命名列索引
df4.rename(index={0: '零', 1: '一', 2: '二', 3: '三', 4: '四', 5: '五', 6: '六'}) # 改行索引
平坦索引
df.reset_index()
5.数据选取
(1)列选择
df6 = pd.DataFrame({'code': [1, 2, 2, 4, 5, 5, 6],
'name': ['a', 'a', 'b', 'c', 'd', 'd', 'e'],
'freq': [2, 3, 4, 2, 1, 4, 5],
'value':[12, 14, 17, 20, 25, 26, 30]})
#选择1列或多列
df6['code']
df6[['code', 'name']]
df6.iloc[:, 1]#获取第2列
df6.iloc[:, [0,2]] # 获取第1列和第三列数据 ,‘:’表示选取所有行
(2)行选择
df7 = pd.DataFrame({'code': [1, 2, 2, 4, 5, 5, 6],
'name': ['a', 'a', 'b', 'c', 'd', 'd', 'e'],
'freq': [2, 3, 4, 2, 1, 4, 5],
'value':[12, 14, 17, 20, 25, 26, 30]},
index=['一','二', '三', '四', '五', '六','七' ])
##选择1行或多行
df7.loc['二']
df7.loc[['二','六']]
df7.iloc[1:3, :]# ':'表示选中所有列
(3)选择满足条件的行
df3 = pd.read_csv(r"data\行业指数pe_ttm.csv", engine='python', skiprows=1)
# 先将时间变量的类型转化成datetime64,选取满足时间条件在2019年2月1日以来数据
df3['时间'] = df3['时间'].astype('datetime64')
df3[df3['时间'] > '2019-02-01']
(4)行列同时选择
df7 = pd.DataFrame({'code': [1, 2, 2, 4, 5, 5, 6],
'name': ['a', 'a', 'b', 'c', 'd', 'd', 'e'],
'freq': [2, 3, 4, 2, 1, 4, 5],
'value':[12, 14, 17, 20, 25, 26, 30]},
index=['一', '二', '三', '四', '五', '六', '七'])
df7
运行结果:
code name freq value
一 1 a 2 12
二 2 a 3 14
三 2 b 4 17
四 4 c 2 20
五 5 d 1 25
六 5 d 4 26
七 6 e 5 30
# 名称索引 + 名称索引
df7.loc[['一', '五'], ['name', 'value']]
name value
一 a 12
五 d 25
行:iloc方法 + 列:iloc方法(传入位置)
#行、列从0开始,[]左右都闭
df7.iloc[[0, 1], [2, 3]]
运行结果:
freq value
一 2 12
二 3 14
# 布尔索引 + 名称索引
df7[df7['value'] > 20][['code', 'name']]
运行结果:
code name
五 5 d
六 5 d
七 6 e
6.数值替换
df7 = pd.DataFrame({'code': [1, 2, 2, 4, 5, 5, 6],
'name': ['a', 'a', 'b', 'c', 'd', 'd', 'e'],
'freq': [2, 3, 4, 2, 1, 4, 5],
'value':[12, 14, 17, 20, 25, 26, 30]},
index=['一', '二', '三', '四', '五', '六', '七'])
(1)一对一替换
df7['value'].replace(17, 20) #把value里面的17替换为20,但是df7没变
df7['value'] = df7['value'].replace(17, 20) #此时df7变了
df7['value'].replace(17, 20, inplace = True)#此时df7变了
(2)多对一替换
df7['value'].replace([17, 20], 30)
(3)多对多替换
df7.replace({'a': 'A', 'b': 'B'})
7.数值排序
(1)按照一列数值进行排序 df.sort_values(by=[col_name], ascending=True)
df3 = pd.read_csv(r"data\行业指数pe_ttm.csv", engine='python', skiprows=1)
df3.sort_values(by='全指金融', ascending=False)
#ascending=True升序ascending=False降序
(2)按照有缺失值的列进行排序,修改 na_position参数
df3.sort_values(by='全指金融', na_position='first') # 将缺失值排在最前或最后
(3)按照多列数值进行排序 df.sort_values(by=[col1, col2], ascending=[True, False])
df3.sort_values(by=['全指金融', '全指医药'], ascending=[True, False])
(4)数值的秩 .rank()方法,其中两个参数,分别是ascending和method
ps:秩对应数值由大到小
df4 = df3.set_index('时间')
df4.rank()/len(df4)
method 说明
average 与Excel中RANK.AVG函数的功能一样,取重复值的平均排名
first 按值在所有待排列数据中出现的先后顺序排名
min 与Excel中RANK.EQ函数的功能一样,取重复值对应的最小排名
max 与min相反,取重复值对应的最大排名
8.数值计数
df4 = pd.read_excel(r"data\个股及其行业数据.xlsx")
df4['industry_sw'].value_counts()
9.唯一值获取
df4['industry_sw'].unique()
10.数值查找
df4['name'].isin(['平安银行']) # 查看平安银行是否在df4中,返回布尔DataFrame
11. 区间划分
#cut方法
pe_min = df4['pe_ttm'].min()
pe_max = df4['pe_ttm'].max()
bins = [pe_min, 0, 20, 60, 100, pe_max]
ca_pe = pd.cut(df4['pe_ttm'], bins, labels=['垃圾股', '低估值', '成长估值', '高估值', '超高股估
值'])
ca_pe
# qcut方法,按照分位数划分
pd.qcut(df4['pe_ttm'], 5).value_counts()
运行结果:
(-7393.975, 13.492] 720
(25.245, 38.696] 720
(66.495, 7476.881] 720
(13.492, 25.245] 719
(38.696, 66.495] 719
Name: pe_ttm, dtype: int64
12.插入新的行或列 .insert(位置, 列名称, 数据)
# 对于列的插入,可以用.insert()函数
df7.insert(2, 'category', ['glass', 'plastic', 'wood', 'beverage', 'steel', 'nylon',
'glass'])
13.行列转置
df7.T
14.索引重塑
df8 = pd.DataFrame({'A1': [1, 2, 2], 'A2': [2, 3, 1], 'A3': [7, 3, 2]}, index=['一', '二',
'三'])
df8 = df8.stack()
df8.unstack()
15.长宽表转换
(1)宽表转换成长表
df5 = pd.read_excel(r"data\2015_2017年A股公司净利润增长率.xlsx", skipfooter=2)
df5.melt(id_vars=['code', 'name'], var_name=['year'], value_name='yoy')
(2)长表转换为宽表
df6.pivot_table(index=['code', 'name'], columns=['year'], values=['yoy'])
16.apply和applymap函数,都是传入函数名,对元素进行操作
df8 = pd.DataFrame({'A1': [1, 2, 2], 'A2': [2, 3, 1], 'A3': [7, 3, 2]}, index=['一', '二',
'三'])
def plusone(x):
return x + 1
df8.apply(plusone)
df8.applymap(plusone)
df8.apply(sum)
df8.applymap(sum) # 报错,这就是区别
17.算术运算和比较运算
(1)算术运算
df8 = pd.DataFrame({'A1': [1, 2, 2], 'A2': [2, 3, 1], 'A3': [7, 3, 2]}, index=['一', '二',
'三'])
df8['A1'] + df8['A3']
df8['A1'] * df8['A3']
df8['A1'] / df8['A3']
df8['A1'] - 2
(2)比较运算
df8['A1'] > df['A3']
df8['A1'] != df8['A2']
(3)汇总运算
<1>count非空值计数
df8.count()
df8.count(axis=1)
<2>sum求和
df8.sum()
<3>mean求均值
df8.mean()
<4>max求最大值
df8.max()
<5>min求最小值
df8.min()
<6>median求中位数
df8.median()
<7>mode求众数
df8.mode()
<8>var方差,std标准差
df8.var()
df8.std()
<9>quantile求分位数
df3 = pd.read_csv(r"dataa\行业指数pe_ttm.csv", engine='python', skiprows=1)
df3.quantile(0.25)
<10>相关性运算
df2 = pd.read_excel(r"data\行业指数.xlsx", skiprows=1)
df2.corr() # 相关性矩阵
df2['全指医药'].corr(df2['全指消费'])
18.导入时间函数
from datetime import datetime
datetime.now()
datetime.now().day
datetime.now().month
datetime.now().year
datetime.now.date()
(1)可以阅读.strftime()函数说明,设置日期格式
datetime.now().strftime('%Y-%m-%d')
(2)将时间格式转换为字符串格式
now = datetime.now()
now_str = strftime(now)
type(now_str)
(3)将字符串格式改为时间格式
str_time = "2018-10-14"
type(str_time)
from dateutil.parser import parse
now = parse(str_time)
type(now)