6.数据分析利器Pandas

首先导入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)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容