以下为本人自学(练习案例和阅读参考书《利用Python进行数据分析》)关于Pandas的用法总结笔记:
【emmmm…也没想到写着写着这么多字】
文章目录
Pandas 的数据结构
Series
简要介绍一下关于Series的基础特征/用法。
- Series的字符串表现形式为:索引在左边,值在右边。由于我们没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引。
- 一维数组,与numpy中的一维array比较相似,和基本数据结构的list也比较相似。
- series.values:调用值
- series.index:调用索引
- 索引取值:若为系统自行设定索引则为左闭右开;若为自行设定索引则为左闭右闭。
import pandas as pd
obj1 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
print(obj1[0:2], obj1['a':'c'])
# d 4
# b 7
# dtype: int64
# a -5
# c 3
# dtype: int64
- 进行运算会保留索引和值之间的对应关系:
print(obj1[obj1 > 0])
# d 4
# b 7
# c 3
# dtype: int64
print(obj1 ** 2)
# d 16
# b 49
# a 25
# c 9
# dtype: int64
- 可以将一个字典直接转成Series的形式:
如果只传入一个字典,则结果Series中的索引就是原字典的键(有序排列)。
example_dict = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 12787}
obj2 = pd.Series(example_dict)
print(obj2)
# Ohio 35000
# Texas 71000
# Oregon 16000
# Utah 12787
# dtype: int64
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj3 = pd.Series(example_dict, index=states)
print(obj3)
# California NaN
# Ohio 35000.0
# Oregon 16000.0
# Texas 71000.0
# dtype: float64
- Series最重要的一个功能是:它在算术运算中会自动对齐不同索引的数据。
print(obj2 + obj3)
# California NaN
# Ohio 70000.0
# Oregon 32000.0
# Texas 142000.0
# Utah NaN
# dtype: float64
- Series对象本身及其索引都有一个name属性。
obj3.name = 'population'
obj3.index.name = 'state'
print(obj3)
# state
# California NaN
# Ohio 35000.0
# Oregon 16000.0
# Texas 71000.0
# Name: population, dtype: float64
DataFrame
由于DataFrame中有一些基础特征和Series相似,就一笔带过了。
- DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。
- 果DataFrame会自动加上索引(跟Series一样),且全部列会被有序排列;如果指定了列序列,则DataFrame的列就会按照指定顺序进行排列;跟Series一样,如果传入的列在数据中找不到,就会产生NA值
- DataFrame只要求每一列数据的格式相同
- pd.Dataframe(values,index=,columns=list(‘str’))
- 可以直接传入一个由等长列表或NumPy数组组成的字典构建DataFrame:
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = pd.DataFrame(data)
print(frame)
# state year pop
# 0 Ohio 2000 1.5
# 1 Ohio 2001 1.7
# 2 Ohio 2002 3.6
# 3 Nevada 2001 2.4
# 4 Nevada 2002 2.9
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['1', '2', '3', '4', '5'])
print(frame2)
# year state pop debt
# 1 2000 Ohio 1.5 NaN
# 2 2001 Ohio 1.7 NaN
# 3 2002 Ohio 3.6 NaN
# 4 2001 Nevada 2.4 NaN
# 5 2002 Nevada 2.9 NaN
- 可以通过属性值直接将DF列数据获得成Series:
print(frame2['year'])
# 1 2000
# 2 2001
# 3 2002
# 4 2001
# 5 2002
# Name: year, dtype: int64
- 列可以通过赋值的方式进行修改;1)可以给那个空列赋上一个标量值或一组值;2)将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值;3)为不存在的列赋值会创建出一个新列
frame2['debt'] = 16.5
print(frame2)
# year state pop debt
# 1 2000 Ohio 1.5 16.5
# 2 2001 Ohio 1.7 16.5
# 3 2002 Ohio 3.6 16.5
# 4 2001 Nevada 2.4 16.5
# 5 2002 Nevada 2.9 16.5
frame2['debt'] = np.arange(5)
print(frame2)
# year state pop debt
# 1 2000 Ohio 1.5 0
# 2 2001 Ohio 1.7 1
# 3 2002 Ohio 3.6 2
# 4 2001 Nevada 2.4 3
# 5 2002 Nevada 2.9 4
frame2['debt'] = np.arange(6)
print(frame2)
# ValueError: Length of values (6) does not match length of index (5)
frame2['debt'] = pd.Series([-1.2, -1.5, -1.7], index=['2', '4', '1'])
print(frame2)
# year state pop debt
# 1 2000 Ohio 1.5 -1.7
# 2 2001 Ohio 1.7 -1.2
# 3 2002 Ohio 3.6 NaN
# 4 2001 Nevada 2.4 -1.5
# 5 2002 Nevada 2.9 NaN
frame2['debt'] = pd.Series([-1.2, -1.5, -1.7])
print(frame2)
# year state pop debt
# 1 2000 Ohio 1.5 NaN
# 2 2001 Ohio 1.7 NaN
# 3 2002 Ohio 3.6 NaN
# 4 2001 Nevada 2.4 NaN
# 5 2002 Nevada 2.9 NaN
frame2['eastern'] = frame2.state == 'Ohio'
print(frame2)
# year state pop debt eastern
# 1 2000 Ohio 1.5 -1.7 True
# 2 2001 Ohio 1.7 -1.2 True
# 3 2002 Ohio 3.6 NaN True
# 4 2001 Nevada 2.4 -1.5 False
# 5 2002 Nevada 2.9 NaN False
- DataFrame可以用类似字典的形式生成,可包含各种类型的数据。
df2 = pd.DataFrame({'A': 2.,
'B': pd.Timestamp('20190101'),
'C': pd.Series(1, index=list(range(4)), dtype=float),
'D': np.array([3] * 4, dtype=int),
'E': pd.Categorical(['test', 'train', 'test', 'train']),
'F': 'abc'})
print(df2)
# A B C D E F
# 0 2.0 2019-01-01 1.0 3 test abc
# 1 2.0 2019-01-01 1.0 3 train abc
# 2 2.0 2019-01-01 1.0 3 test abc
# 3 2.0 2019-01-01 1.0 3 train abc
- 数据表中有空值的时候调用np.nan
索引相关处理
- df.set_index(‘column’):将某一列换成索引
df = pd.read_csv(r'CPS1988.csv') # 除了可以csv还可以导入txt,text,excel
print(df.head(6))
df['id'] = range(202001, len(df) + 202001)
df = df.set_index('id')
print(df.head(6))
Series
- pd.index.name=‘str’:为Series索引设置名称
- object[‘index’]=element:为Series添加新元素
- 切片:默认索引值切片不包括end,自定义索引值切片包括end
- obj.reindex():
调用该Series的reindex将会根据新索引进行重排。如果某个索引值当前不存在,就引入缺失值
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
print(obj)
# d 4.5
# b 7.2
# a -5.3
# c 3.6
# dtype: float64
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
print(obj2)
# a -5.3
# b 7.2
# c 3.6
# d 4.5
# e NaN
# dtype: float64
obj3 = obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
print(obj3)
# a -5.3
# b 7.2
# c 3.6
# d 4.5
# e 0.0
# dtype: float64
- reindex的插值选项:
ffill / pad:前向填充(搬运)值
bfill / backfill:后向填充(搬运)值
obj4 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
print(obj4)
# 0 blue
# 2 purple
# 4 yellow
# dtype: object
obj5 = obj4.reindex(range(6),method='ffill')
print(obj5)
# 0 blue
# 1 blue
# 2 purple
# 3 purple
# 4 yellow
# 5 yellow
# dtype: object
DataFrame
- 对于DataFrame,reindex可以修改(行)索引、列,或两个都修改。 如果仅传入一个序列,则会重新索引行;使用columns关键字即可重新索引列;也可以同时对行和列进行重新索引,而插值则只能按行应用
frame = pd.DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])
print(frame)
# Ohio Texas California
# a 0 1 2
# c 3 4 5
# d 6 7 8
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
print(frame2)
# Ohio Texas California
# a 0.0 1.0 2.0
# b NaN NaN NaN
# c 3.0 4.0 5.0
# d 6.0 7.0 8.0
state = ['Texas', 'Ohio', 'California', 'Utah']
frame3 = frame2.reindex(columns=state)
print(frame3)
# Texas Ohio California Utah
# a 1.0 0.0 2.0 NaN
# b NaN NaN NaN NaN
# c 4.0 3.0 5.0 NaN
# d 7.0 6.0 8.0 NaN
- 重新赋值索引将0开始变成1开始,可以使用
practice_soccer.index = range(1, len(practice_soccer) + 1)
修改列名
df.columns = [] # 后面接新列名列表即可
Dataframe转换成list
- df.values.tolist():将每一行全部数据做成一个列表,各行构成大列表
- df.columns1.tolist():将columns1的每一行数据直接生成列表。下述代码即为示例。
print(monthly_data_2016, monthly_data_2016.Month.tolist())
# Month
# 2 765
# 3 4352
# 4 12037
# 5 12471
# 6 20380
# 7 30654
# 8 37362
# 9 34934
# 10 36738
# 11 41917
# 12 39271 [765, 4352, 12037, 12471, 20380, 30654, 37362, 34934, 36738, 41917, 39271]
Dataframe打乱
- df.sample(frac=1,random_state=0)
frac表示抽取数据的比例,1为100%,random_state代表随机种子
数据显示设置
- pd.set_option():
pd.set_option('max_column', 5) # 最大显示5列
pd.set_option('max_row', 5) # 最大显示5行
pd.set_option('max_column', None) # 显示全部列
pd.set_option('max_row', None) # 显示全部行
数据查询
常用查询方式
- obj.head() 默认查看前五个数据
- obj.tail() 默认查看后五个数据
- obj.take([index,index,…]) / obj[[index,index,…]] 用自行命名索引值或数据0,1,2,3…均可
- obj.columns 查看列名
- obj.index 查看索引名
- obj.values 查看数据值
- obj.describe() 查看各变量的描述性统计
practice_soccer = pd.read_excel(r'校足球队球员信息(身份证号及尺码).xlsx')
print(practice_soccer.describe())
# 身高 体重 球衣号码
# count 16.00000 16.000000 16.000000
# mean 175.87500 71.531250 13.187500
# std 5.08429 10.015769 7.721992
# min 168.00000 56.000000 1.000000
# 25% 171.50000 64.750000 8.500000
# 50% 177.00000 69.750000 12.500000
# 75% 179.00000 76.750000 18.750000
# max 187.00000 90.000000 27.000000
- obj.column.max()/obj[[‘column’,‘column’]].max()
同样,这些也可以~ min() .var() .corr() .cov() .count() .std() .sum() - obj.column.unique() 该列中数据的不同种类
- obj.column.value_counts()该列中数据的不同种类的个数
- obj.column.replace([,],[,],inplace=l)
- obj[[‘column1’,‘column2’,…]][:]
print(excel[['姓名', '邮箱']][:5])
# 姓名 邮箱
# 0 马某某 maxiassxss09@qq.com
# 1 蒋某某 8621x8xx88@qq.com
# 2 张某某 1581148xxxx3@163.com
# 3 胡某某 15932x328xxx@163.com
# 4 唐某 5158xxxxx87@qq.com
- obj.iloc[row_indexer,column_indexer]:位置索引与切片
df.loc[[index],[column]]
obj.iloc[2] # 第三行数据
obj.iloc[:,2] # 第三列数据
obj.iloc[[1,4],[2,3]] # 第二行和第五行的第三列第四列值
obj.iloc[1:4,2:3]
obj.iloc[3,3] # 第四行第四列的值
obj.iloc[1:3,obj.iloc[3]>0] # 根据布尔值进行提取
【iloc用position去定位;loc用label去定位】
重置索引的方式来查看数据
practice_soccer = pd.read_excel(r'校足球队球员信息(身份证号及尺码).xlsx')
practice_soccer = practice_soccer.set_index(['球衣尺码', '身高'])
print(practice_soccer)
print(practice_soccer.loc['xl']) # 直接选出xl的人员
practice_soccer = practice_soccer.swaplevel('球衣尺码', '身高')
print(practice_soccer.loc[178.0]) # 直接选出178的人员
stack() & unstack()查看数据
- 直接扔代码和图啦
s = pd.Series(np.arange(1, 10), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'],
[1, 2, 3, 1, 2, 3, 1, 2, 3]])
print(s, '\n', type(s), '\n', s.index)
print()
print(s.unstack()) # Series没有stack()
print()
data = pd.DataFrame(np.arange(1, 13).reshape(4, 3),
index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
columns=[['A', 'B', 'A'], ['Z', 'X', 'C']])
data.index.names = ['row1', 'row2']
data.columns.names = ['col1', 'col2']
print(data)
print()
print(data.stack())
print()
print(data.unstack())
print()
print(data.swaplevel('row1', 'row2'))
print()
print(data['A'])
条件选择
超爱条件选择!具体参见代码例子。
- excel[(excel.序号 % 2 == 0) & (excel.学号 > 202018)][[‘姓名’, ‘学号’, ‘序号’]][:4]
- excel[((excel.序号 % 2 == 0) | (excel.序号 % 3 == 0)) & (excel.学号 > 202018)][[‘姓名’, ‘学号’, ‘序号’]]
【练习是拿班级名单做的,在这就只保留姓氏了>︿<】
# 条件选择
excel.index.name = '索引'
print(excel[excel['序号'] % 2 == 0][['姓名', '学号', '序号']][:4])
# 姓名 学号 序号
# 索引
# 1 蒋 202002 2
# 3 胡 202004 4
# 5 齐 202006 6
# 7 李 202008 8
print(excel[(excel.序号 % 2 == 0) & (excel.学号 > 202018)][['姓名', '学号', '序号']][:4])
# 姓名 学号 序号
# 索引
# 19 李 202020 20
# 21 刘 202022 22
# 23 门 202024 24
# 25 郭 202026 26
print(excel[((excel.序号 % 2 == 0) | (excel.序号 % 3 == 0)) & (excel.学号 > 202018)]
[['姓名', '学号', '序号']])
# 姓名 学号 序号
# 索引
# 19 李 202020 20
# 20 徐 202021 21
# 21 刘 202022 22
# 23 门 202024 24
print(excel[excel.姓名.str.contains('李') | excel.姓名.str.contains('王')]
[['姓名', '学号', '序号']])
# 姓名 学号 序号
# 索引
# 6 王 202007 7
# 7 李 202008 8
# 19 李 202020 20
# 31 李 202032 32
# 35 王 202036 36
排序与排名
- obj.sort_index():直接用索引排序
- obj.sort_values():单/多类别排序
by=[‘column1’,‘column2’]----列表时,从左到右的顺序依次排序,后面是否升序的列表对应着by中类别的列表。
print(excel.sort_values(by='电话', ascending=False)) # 降序排列
print(excel.sort_values(by=['序号', '电话'], ascending=[False, True]))
- 有时候我们希望按照特定的顺序去排序,而不是单纯的升降序,那就按照以下的方法操作啦
practice_soccer = pd.read_excel(r'校足球队球员信息(身份证号及尺码).xlsx')
list_custom = ['最小', 's', 'm', 'l', 'xl', 'xxl', 'xxxl', '最大']
practice_soccer['球衣尺码'] = practice_soccer['球衣尺码'].astype('category')
practice_soccer['球衣尺码'].cat.reorder_categories(list_custom, inplace=True)
practice_soccer.sort_values('球衣尺码', inplace=True)
print(practice_soccer)
这是原始的数据:
就变成了这样子:
- obj.rank():rank用于显示所有数据的排序名次
数据之增删改
增加
- obj[‘columns’]=data:新增加一列
excel['学号'] = range(202001, len(excel) + 202001)
print(excel[-3:])
# 序号 姓名 电话 邮箱 学号
# 36 37 索某某某 1.881304e+10 1061262xx9@qq.com 202037
# 37 38 马某某 1.770903e+10 591985xx6@qq.com 202038
# 39 40 tony 1.231412e+09 dde2@163.com 202039
合并
- df = df [list(‘ABCD’]:横向合并
concat
- 多个数据集进行批量合并 重点是多个数据集,单个无效,但可以列表中遍历操作
pd.concat([stock_data_list[i]['returns'] for i in range(0, len(stock_data_list))], axis=1)
- 默认axis=0,为行合并,如果为列合并需要改为1
- pd.concat( [df ,s1 ] ,axis=1):横向合并
- pd.concat([df1,df2,df3],axis=0) :纵向合并
- pd.concat( [df,df1], join=‘inner’) :纵向合并——只保留新加数据所在列
merge
- pd.merge(ps1, ps2, how=‘inner’, on=‘姓名’):两个数据集横向合并
当数据量过大的时候,merge运行速度会很慢—>多线程计算。
append
- df.append(df1) :纵向合并——对应列名一致 所有数据均在
data = [10, 11, 12]
index = ['a', 'b', 'c']
s = pd.Series(data=data, index=index) # array数组
s1 = s.copy()
s2 = pd.Series(data=[1, 23], index=['sd', 's'])
s3 = s1.append(s2)
print(s3)
# a 101
# b 11
# c 12
# sd 1
# s 23
# dtype: int64
删除
- del obj / del obj[‘i’]
- obj.drop():删除某列或某行
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj = obj.drop(['c', 'd'])
print(obj)
# a 0.0
# b 1.0
# e 4.0
# dtype: float64
data = pd.DataFrame(np.arange(16).reshape((4, 4)), index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data1 = data.drop(['Ohio', 'Utah'])
print(data1)
# one two three four
# Colorado 4 5 6 7
# New York 12 13 14 15
data2 = data.drop('two', axis=1)
print(data2)
# one three four
# Ohio 0 2 3
# Colorado 4 6 7
# Utah 8 10 11
# New York 12 14 15
替代
- obj.copy():为了防止更改原数据
obj.replace():更改数据
data = [10, 11, 12]
index = ['a', 'b', 'c']
s = pd.Series(data=data, index=index) # array数组
s1 = s.copy()
s1.replace(to_replace=10, value=101, inplace=True)
print(s)
print(s1)
# a 10
# b 11
# c 12
# dtype: int64
# a 101
# b 11
# c 12
# dtype: int64
practice_soccer.球衣尺码.replace(['最小', '最大'], ['s', 'xxxl'], inplace=True)
简单运算
- 基础运算与Numpy相似,不多赘述。
df3 = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], index=['a', 'b', 'c'], columns=['A', 'B', 'C'])
print(df3)
# A B C
# a 1 2 3
# b 4 5 6
# c 7 8 9
print(df3.sum()) # 默认按照列求和,类似可以有min(),max(),mean(),median()...
# A 12
# B 15
# C 18
# dtype: int64
print(df3.sum(axis=1)) # axis=1则为按照行求和 axis='index'/'columns'
# a 6
# b 15
# c 24
# dtype: int64
- 相关关系
df4 = pd.read_csv('CPS1988.csv')
print(df4.head())
print(df4.corr())
函数应用与映射
-
DataFrame.apply(func,axis=0) #axis=0默认为对列操作;为1则为对行操作
Eg:df.apply(max, axis=0) -
也可以自定义函数
Eg:
f = lambda x:x.max()-x.min()
df.apply(f,axis=1) -
map映射:
数据格式查看/转换
- obj.T:转置
- obj.index:查看数据索引
- obj.columns:查看数据类别
- obj.values:查看数据;为array数组结构,当API文档有特殊要求的时候经常使用
- obj.dtypes:查看数据类型,或在打开文件时设置数据类型
Eg:excel = pd.read_excel(r’20专硕班级人员信息表.xls’, dtype=‘str’)
print(df2)
# A B C D E F
# 0 2.0 2019-01-01 1.0 3 test abc
# 1 2.0 2019-01-01 1.0 3 train abc
# 2 2.0 2019-01-01 1.0 3 test abc
# 3 2.0 2019-01-01 1.0 3 train abc
print(df2.dtypes)
# A float64
# B datetime64[ns]
# C float64
# D int32
# E category
# F object
# dtype: object
- obj.astype():数据转换
excel['电话'] = excel['电话'].astype('str')
缺失/异常数据处理
检测缺失数据
- pd.isnull(obj) / obj.isnull():检测缺失,返回布尔值,判断哪些为缺失值
- pd.notnull(obj) / obj.notnull():检测未缺失
缺失值处理
- pd.dropna():根据标签中的缺失值进行过滤,删除缺失值
how=‘all’ 删除全为空值的行或列
how=‘any’ 删除只要含有空值的列或行
inplace=True 覆盖之前的数据
axis=0/1 选择列或行
subset=[] 对[]中的列进行查找缺失值 - pd.drop_duplicates()
- pd.fillna()对缺失值进行填充
- pd.drop(‘xx’) #删除xx所在行
excel['电话'].fillna('未知电话', inplace=True)
# 用‘未知电话’填充缺失值,并改变原数据
异常值处理
比如通过查询电话号码的长度来判断是否有异常值出现,会返回布尔类型。
print(excel.电话.str.len() == 11)
重复值删除
- df.duplicated() 得到布尔类型的Series表示各行是否为重复行
- df.duplicates() 即可移除重复行
- df.duplicated([‘c’]) /df.duplicates([‘c’]) 针对某一列进行重复项的判断
- df.drop_duplicates(subset=‘k1’) # 只保留k1不同的数据值
数据透视
- 基础形式 pd.pivot_table()
- 可以有多个索引,实际上,大多数的pivot_table参数可以通过列表获取多个值;可以指定需要统计汇总的数据;可以指定函数,来统计不同的统计值
- 非数值(NaN)难以处理。如果想要移除它们,可以使用fill_value将其设置为0;加入margins=True,可以在下方显示一些综合数据;aggfunc=设置函数,若想对各个类别计算不同的函数则采用字典形式,否则列表形式。
print(pd.pivot_table(practice_soccer, index=['球衣尺码']))
# 体重 球衣号码 身高
# 球衣尺码
# 最小 56.000000 21.000000 170.0
# s 58.000000 17.000000 169.0
# m 65.000000 11.000000 170.0
# l 65.125000 9.000000 174.0
# xl 74.666667 12.833333 179.5
# xxl 79.000000 13.000000 180.0
# xxxl 90.000000 14.000000 172.0
# 最大 88.000000 22.000000 180.0
print(pd.pivot_table(practice_soccer, index=['球衣尺码', '身高']))
# 体重 球衣号码
# 球衣尺码 身高
# 最小 170.0 56.0 21.0
# s 169.0 58.0 17.0
# m 170.0 65.0 11.0
# l 168.0 64.0 12.0
# 174.0 63.0 2.0
# 176.0 65.0 4.0
# 178.0 68.5 18.0
# xl 176.0 76.0 1.0
# 178.0 71.5 16.0
# 179.0 73.0 17.0
# 187.0 83.0 10.0
# xxl 180.0 79.0 13.0
# xxxl 172.0 90.0 14.0
# 最大 180.0 88.0 22.0
print(pd.pivot_table(practice_soccer, index=['球衣尺码'],
values=['体重', '身高'], aggfunc=np.mean))
# 体重 身高
# 球衣尺码
# 最小 56.000000 170.0
# s 58.000000 169.0
# m 65.000000 170.0
# l 65.125000 174.0
# xl 74.666667 179.5
# xxl 79.000000 180.0
# xxxl 90.000000 172.0
# 最大 88.000000 180.0
print(pd.pivot_table(practice_soccer, index=['球衣尺码'], values=['体重', '身高'],
aggfunc=[np.mean, np.max], fill_value=0, margins=True))
# mean amax
# 体重 身高 体重 身高
# 球衣尺码
# 最小 56.000000 170.000 56.0 170
# s 58.000000 169.000 58.0 169
# m 65.000000 170.000 65.0 170
# l 65.125000 174.000 68.5 178
# xl 74.666667 179.500 83.0 187
# xxl 79.000000 180.000 79.0 180
# xxxl 90.000000 172.000 90.0 172
# 最大 88.000000 180.000 88.0 180
# All 71.531250 175.875 90.0 187
print(pd.pivot_table(practice_soccer, index=['球衣尺码'], values=['体重', '身高'],
aggfunc={'体重': np.mean, '身高': np.max}, fill_value=0, margins=True))
# 体重 身高
# 球衣尺码
# 最小 56.000000 170
# s 58.000000 169
# m 65.000000 170
# l 65.125000 178
# xl 74.666667 187
# xxl 79.000000 180
# xxxl 90.000000 172
# 最大 88.000000 180
# All 71.531250 187
数据分组,分组运算
obj.value_counts():分组计数
df4 = pd.read_csv('CPS1988.csv')
print(df4.education.value_counts())
print(df4.education.value_counts(ascending=True, bins=6)) # 通过bins设定分组个数;注:这里的ascending是指计数的升序
obj.groupby():分组计算
df2 = pd.read_csv(r'CPS1988.csv')
print(df2)
print(df2.groupby('education')['wage'].mean())
设置分位数
practice_soccer['身高等级'] = pd.cut(practice_soccer['身高'],
[165, 170, 175, 180, 185, 190],
labels=['E', 'D', 'C', 'B', 'A'])
bins = np.percentile(practice_soccer['体重'], [0, 25, 50, 75, 100])
practice_soccer['体重分位数'] = pd.cut(practice_soccer['体重'], bins,
labels=['B-', 'A-', 'A+', 'B+'])
print(practice_soccer)
时间序列处理
- 日期不多时:
date = pd.Timestamp(datetime(y,m,d))
series = pd.Series(value, index=[date]) - 日期繁多时:
series = pd.Series([value1,value2,value3],index=pd.to_datetime([‘yyyy-mm-dd’,‘yyyy-mm-dd’,‘yyyy-mm-dd’])) - datetime对象可以直接将其作为index,而Pandas会自动将其转换成Timestamp对象
- 时间序列切片:obj.truncate(after=‘yyyy-mm-dd’)
- 时间滞后和超前:obj.shift(num)
正数为滞后,负数为超前---->此可用于计算收益率:Eg: (price-price.shift(1))/price.shift(1) - 高低频时间数据转换:obj.resample(‘M’,how=first) 'M’每月最后一天;'MS’每月第一天
保存数据
- obj.to_excel(‘xxxx.xlsx’):保存在与代码同一路径下文件夹中
- obj.to_csv(‘xxxx.xlsx’)
打开文件
- pd.read_table(‘data_file’,sep=’\t’,header=None,names=None) # header=0 默认取值,指的是用第0行数据作为列名,header = None是没有列名,names可以指定各列变量名
- pd.read_csv(‘filepath/test.csv’, header=None,sep=’,’) # header=None是没有列表名
- pd.read_excel(‘filepath/test.xlsx’, header=None,sheet_name=0) # sheet_name是指excel文件的sheet