Python __ Pandas
简介
可以看做是Excel
是基于Numpy的.
优点:处理表格数据(混杂数据)
需要引用:import pandas as pd
Series(无用)
类似于Numpy的一维数组
优点:相较于Nump索引功能强大
输出默认带索引:(当为字典是,,默认键是索引)
s4 = pd.Series([9.53,9.62,9.72])
创建时可以指定索引:
s5 = pd.Series([1, np.nan, 7.0, 'abc'], index=['a','b','c','d'])
DataFrame(常用)
类似于Numpy的二维数组
基本操作
获取行列数据
在 Pandas 中,有多个方法可以选取和重新组合数据,如表所示:
方法 | 说明 |
---|---|
df[val] | 从DataFrame中选取单列或多列。val为布尔型数组时,过滤行; val为切片时,行切片 |
df.loc[val] | 通过val选取单行或多行 |
df.loc[;,val] | 通过val选取单列或多列 |
df.loc[val1,val2] | 选取val1行、val2列的值 |
df.iloc[val] | 通过整数位置,选取单行或多行 |
df.iloc[;,val] | 通过整数位置,选取单列或多列 |
df.iloc[val1, val2] | 通过整数位置,选取val1 行、val2列的值 |
具体说明如下:
1、读取行
如果想从 DataFrame 中获取某一行数据,可以通过位置或名称进行获取。
读取行有三种方法,分别是loc,iloc,ix。
方法名 | 参数 | 备注 |
---|---|---|
loc | 行标签 | 可以使用元组 |
iloc | 行号 | 可以进行切片 |
ix | iloc和loc的并 | 不推荐使用IX索引器,已弃用 |
示例:
- loc通过行标签索引来确定行的
import pandas as pd d=[[1,2,3,4],[5,6,7,8]] index=["one","two"] df=pd.DataFrame(d, index=index) print df.loc["one"]
- iloc通过行号索引来确定行
import pandas as pd d=[[1,2,3,4],[5,6,7,8]] index=["one","two"] df=pd.DataFrame(d, index=index) print df.iloc[0]
2、读取列
如果想从 DataFrame 中获取某一列数据为一个 Series, 可以通过类似字典标记或属性的方式:
[]
括号里可以是列标签/列号
实例:
print df5['浦发银行'] #也可以是 df5[0] #2020-10-14 9.53 #2020-10-15 9.62 #2020-10-16 9.72 #Name: 浦发银行, dtype: float64 df5[['浦发银行','民生银行']] #可以是个元组 # 浦发银行 民生银行 #2020-10-14 9.53 5.33 #2020-10-15 9.62 5.35 #2020-10-16 9.72 5.39 df5[df5['浦发银行'] > 9.6] # 同时可以进行筛选数据 # 浦发银行 民生银行 #2020-10-15 9.62 5.35 #2020-10-16 9.72 5.39
对某列进行 单值筛选
找出df中A列值为100的所有数据
1 df[df.A==100] # A B C # 0 100 a 1
用序列对某列筛选:isin
找出df中A列,值为100、200、300的所有数据
num = [100, 200, 300] df[df.A.isin(num)] #筛选出A列值在num列表的数据条 # A B C # 0 100 a 1 # 1 200 b 2 # 2 300 c 3
对多列 进行筛选
多条件筛选的时候,必须加括号()
- 找出df中A列值为100且B列值为‘a’的所有数据
df[(df.A==100)&(df.B=='a')] # A B C # 0 100 a 1
- 找出df中A列值为100或B列值为‘b’的所有数据
df[(df.A==100)|(df.B=='b')] # A B C # 0 100 a 1 # 1 200 b 2
对行列赋值
对DataFrame中某一列的值进行修改,可通过直接赋值一个标量值或一组值:
df5 = pd.DataFrame({'a':[1,2,3],'b':[5,6,7], 'c':[9,10,11],'d':[13,14,15]}, index=['x','y','z']) # a b c d #x 1 5 9 13 #y 2 6 10 14 #z 3 7 11 15 df5['d'] = 1 # 对d列赋值为1 # a b c d #x 1 5 9 1 #y 2 6 10 1 #z 3 7 11 1 df5['d'] = np.arange(3) # 对d列赋值为np.arange(3) # a b c d #x 1 5 9 0 #y 2 6 10 1 #z 3 7 11 2
如果赋值给一个 Series, 则会精准匹配对应索引的数值, 若 Series 缺失 DataFrame 某些索引,则对应位置为空:
df5['d'] = pd.Series([2,5,9],index = ['y','z','a']) df5
增删数据
找出df中A列值为100的所有数据
1 df[df.A==100] # A B C # 0 100 a 1
保留想要的列或删除指定列
保留想要的列
# 方法1: df=df.loc[:,[‘name1’,‘name2’,‘name3’]] # 方法2: df2=df[[‘name1’,‘name2’,‘name3’]]
删除指定列
# 方法1:指定列名删除 df.drop([‘name1’,‘name2’],axis=1,inplace=True) # 方法2:指定列数删除 df.drop(df.columns[0:n], axis=1, inplace=True)
修改行标签和列标签
修改列名
问题:
有一个DataFrame,列名为:['b', 'd', '$e']
现需要改为:['a', 'b', 'c', 'd', 'e']
import pandas as pd df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})
解决:
方式一:columns属性
# ①暴力 df.columns = ['a', 'b', 'c', 'd', 'e'] # ②修改 df.columns = df.columns.str.strip('$') # ③修改 df.columns = df.columns.map(lambda x:x[1:])
方式二:rename方法、columns参数
# ④暴力(好处:也可只修改特定的列) df.rename(columns=('$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}, inplace=True) # ⑤修改 df.rename(columns=lambda x:x.replace('$',''), inplace=True)
获取列名列表
DataFrame.columns.values.tolist()
常用方法
reindex()
表示重新索引,如果某个索引值当前不存在,就会引入
缺失值;可以通过fill_value参数填充默认值,也可以通过method参数设置填充方法;
reindex方法的methon参数的选项:
ffill或pad 前向填充值
bfill或backfill 后向填充值
或者是fill_value直接指定缺失值为多少
汇总,计算和描述性统计
Pandas 拥有一套常用的数学和统计方法, 但都是基于没有缺失数据的假设而构建的。
常用方法
读取excel表中的多个sheet
对于导入xlsx,pandas默认只导入第一个sheet,如果想导入多个/其他sheet需要指定:
# 按照index读取,1代表第二张表,默认是0 即默认只读取第一张表 >>> df = pd.read_excel(r'D:\myExcel/1.xlsx', sheet_name=1) >>> df name Chinese 0 lc 78 1 lb 79 # 按照表名读取 >>> df = pd.read_excel(r'D:\myExcel/1.xlsx', sheet_name='Sheet2') >>> df name Chinese 0 lc 78 1 lb 79 # 同时读取两张表,输入参数为列表 # 返回的是一个有序字典 >>> dfs = pd.read_excel(r'D:\myExcel/1.xlsx', sheet_name=[0, 'Sheet3']) >>> dfs OrderedDict([(0, name math science 0 bob 23 12 1 millor 32 32 2 jiken 61 89 3 tom 34 94 4 json 83 12 5 dela 96 67 6 rison 90 34), ('Sheet3', name English 0 ld 32 1 by 98)])
找到缺失值的位置
问题描述:
判断缺失值一般采用 isnull()
,然而生成的却是所有数据的true/false矩阵,对于庞大的数据dataframe,很难一眼看出来哪个数据缺失,一共有多少个缺失数据,缺失数据的位置。
首先对于存在缺失值的数据,如下所示
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10,6)) # Make a few areas have NaN values df.iloc[1:3,1] = np.nan df.iloc[5,3] = np.nan df.iloc[7:9,5] = np.nan # 0 1 2 3 4 5 # 0 0.520113 0.884000 1.260966 -0.236597 0.312972 -0.196281 # 1 -0.837552 NaN 0.143017 0.862355 0.346550 0.842952 # 2 -0.452595 NaN -0.420790 0.456215 1.203459 0.527425 # 3 0.317503 -0.917042 1.780938 -1.584102 0.432745 0.389797 # 4 -0.722852 1.704820 -0.113821 -1.466458 0.083002 0.011722 # 5 -0.622851 -0.251935 -1.498837 NaN 1.098323 0.273814 # 6 0.329585 0.075312 -0.690209 -3.807924 0.489317 -0.841368 # 7 -1.123433 -1.187496 1.868894 -2.046456 -0.949718 NaN # 8 1.133880 -0.110447 0.050385 -1.158387 0.188222 NaN # 9 -0.513741 1.196259 0.704537 0.982395 -0.585040 -1.693810
df.isnull()
df.isnull()
会产生如下结果
0 1 2 3 4 5 0 False False False False False False 1 False True False False False False 2 False True False False False False 3 False False False False False False 4 False False False False False False 5 False False False True False False 6 False False False False False False 7 False False False False False True 8 False False False False False True 9 False False False False False False
判断哪些”列”存在缺失值
df.isnull().any()
则会判断哪些”列”存在缺失值
0 False 1 True 2 False 3 True 4 False 5 True dtype: bool
只显示存在缺失值的行列
df[df.isnull().values==True]
可以只显示存在缺失值的行列,清楚的确定缺失值的位置。
df[df.isnull().values==True] # Out[126]: # 0 1 2 3 4 5 # 1 1.090872 NaN -0.287612 -0.239234 -0.589897 1.849413 # 2 -1.384721 NaN -0.158293 0.011798 -0.564906 -0.607121 # 5 -0.477590 -2.696239 0.312837 NaN 0.404196 -0.797050 # 7 0.369665 -0.268898 -0.344523 -0.094436 0.214753 NaN # 8 -0.114483 -0.842322 0.164269 -0.812866 -0.601757 NaN
日期数据的处理
日期数据转化
对于转成int常常除以
# string to datetime df['date'] = pd.to_datetime(df['date']) # datetime to int pd.to_datetime('1970-01-01').value// 10 ** 9 # 整列datetime to int df['date'] = df['date'].apply(lambda x: x.value)// 10 ** 9 df['time'] = (df['time']* 10 ** 9).apply(pd.Timestamp)
按日期筛选数据
按年度获取数据
print('---------获取2013年的数据-----------') print(df['2013'].head(2)) # 获取2013年的数据 print(df['2013'].tail(2)) # 获取2013年的数据 ---------获取2013年的数据----------- number date 2013-10-24 3 2013-10-25 4 number date 2013-12-27 2 2013-12-30 2
获取2016至2017年的数据
print('---------获取2016至2017年的数据-----------') print(df['2016':'2017'].head(2)) #获取2016至2017年的数据 print(df['2016':'2017'].tail(2)) #获取2016至2017年的数据 ---------获取2016至2017年的数据----------- number date 2016-01-04 4 2016-01-07 6 number date 2017-02-14 6 2017-02-22 6
获取某月的数据
print('---------获取某月的数据-----------') print(df['2013-11']) # 获取某月的数据 ---------获取某月的数据----------- number date 2013-11-04 1 2013-11-06 3 2013-11-08 1 2013-11-12 5 2013-11-14 2 2013-11-25 1 2013-11-29 1
获取具体某天的数据
* 请注意dataframe类型的数据,获取具体某天的数据时,跟series是有些差异的,详细情况如下述代码所示: # 按日期筛选数据 print('---------获取具体某天的数据-----------') # 获取具体某天的数据 print(s['2013-11-06']) # 获取具体某天的数据,用datafrme直接选取某天时会报错,而series的数据就没有问题 # print(df['2013-11-06']) #可以考虑用区间来获取某天的数据 print(df['2013-11-06':'2013-11-06']) ---------获取具体某天的数据----------- 3 number date 2013-11-06 3 * dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据 * 但一般建议直接用切片(slice),这样更为直观,方便 # dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据 # 但一般建议直接用切片(slice),这样更为直观,方便 print('---------获取某个时期之前或之后的数据-----------') print('--------after------------') print(df.truncate(after = '2013-11')) print('--------before------------') print(df.truncate(before='2017-02')) ---------获取某个时期之前或之后的数据----------- --------after------------ number date 2013-10-24 3 2013-10-25 4 2013-10-29 2 2013-10-30 1 --------before------------ number date 2017-02-07 8 2017-02-14 6 2017-02-22 6
按日期显示数据
to_period()方法
- 请注意df.index的数据类型是DatetimeIndex;
- df_peirod的数据类型是PeriodIndex
按月显示,但不统计
df_period = df.to_period('M') #按月显示,但不统计 print(type(df_period)) print(type(df_period.index)) # 请注意df.index的数据类型是DatetimeIndex; # df_peirod的数据类型是PeriodIndex print(df_period.head()) <class 'pandas.core.frame.DataFrame'> <class 'pandas.tseries.period.PeriodIndex'> number date 2013-10 3 2013-10 4 2013-10 2 2013-10 1 2013-11 1
按季度显示,但不统计
print(df.to_period('Q').head()) #按季度显示,但不统计 number date 2013Q4 3 2013Q4 4 2013Q4 2 2013Q4 1 2013Q4 1
按年度显示,但不统计
print(df.to_period('A').head()) #按年度显示,但不统计 number date 2013 3 2013 4 2013 2 2013 1 2013 1
asfreq()方法
按年度频率显示
df_period.index.asfreq('A') # 'A'默认是'A-DEC',其他如'A-JAN' PeriodIndex(['2013', '2013', '2013', '2013', '2013', '2013', '2013', '2013', '2013', '2013', ... '2017', '2017', '2017', '2017', '2017', '2017', '2017', '2017', '2017', '2017'], dtype='period[A-DEC]', name='date', length=425, freq='A-DEC') df_period.index.asfreq('A-JAN') # 'A'默认是'A-DEC',其他如'A-JAN' PeriodIndex(['2014', '2014', '2014', '2014', '2014', '2014', '2014', '2014', '2014', '2014', ... '2017', '2017', '2017', '2017', '2017', '2017', '2017', '2018', '2018', '2018'], dtype='period[A-JAN]', name='date', length=425, freq='A-JAN')
- 按年度频率在不同情形下的显示,可参考下图所示:
按季度频率显示
df_period.index.asfreq('Q') # 'Q'默认是'Q-DEC',其他如“Q-SEP”,“Q-FEB” PeriodIndex(['2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', ... '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1'], dtype='period[Q-DEC]', name='date', length=425, freq='Q-DEC') df_period.index.asfreq('Q-SEP') # 可以显示不同的季度财年,“Q-SEP”,“Q-FEB” # df_period.index = df_period.index.asfreq('Q-DEC') # 可以显示不同的季度财年,“Q-SEP”,“Q-FEB” # print(df_period.head()) PeriodIndex(['2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', ... '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2'], dtype='period[Q-SEP]', name='date', length=425, freq='Q-SEP')
- 按季度频率在不同情形下的显示,可参考下图所示:
按月度频率显示
df_period.index.asfreq('M') # 按月份显示 PeriodIndex(['2013-10', '2013-10', '2013-10', '2013-10', '2013-11', '2013-11', '2013-11', '2013-11', '2013-11', '2013-11', ... '2017-01', '2017-01', '2017-01', '2017-01', '2017-01', '2017-01', '2017-01', '2017-02', '2017-02', '2017-02'], dtype='period[M]', name='date', length=425, freq='M')
按工作日显示
- method 1
df_period.index.asfreq('B', how='start') # 按工作日期显示 PeriodIndex(['2013-10-01', '2013-10-01', '2013-10-01', '2013-10-01', '2013-11-01', '2013-11-01', '2013-11-01', '2013-11-01', '2013-11-01', '2013-11-01', ... '2017-01-02', '2017-01-02', '2017-01-02', '2017-01-02', '2017-01-02', '2017-01-02', '2017-01-02', '2017-02-01', '2017-02-01', '2017-02-01'], dtype='period[B]', name='date', length=425, freq='B')
- method 2
df_period.index.asfreq('B', how='end') # 按工作日期显示 PeriodIndex(['2013-10-31', '2013-10-31', '2013-10-31', '2013-10-31', '2013-11-29', '2013-11-29', '2013-11-29', '2013-11-29', '2013-11-29', '2013-11-29', ... '2017-01-31', '2017-01-31', '2017-01-31', '2017-01-31', '2017-01-31', '2017-01-31', '2017-01-31', '2017-02-28', '2017-02-28', '2017-02-28'], dtype='period[B]', name='date', length=425, freq='B')
按日期统计数据
按日期统计数据
按周统计数据
print(df.resample('w').sum().head()) # “w”,week number date 2013-10-27 7.0 2013-11-03 3.0 2013-11-10 5.0 2013-11-17 7.0 2013-11-24 NaN
按月统计数据
print(df.resample('M').sum().head()) # "MS"是每个月第一天为开始日期, "M"是每个月最后一天 number date 2013-10-31 10 2013-11-30 14 2013-12-31 27 2014-01-31 16 2014-02-28 4
按季度统计数据
print(df.resample('Q').sum().head()) # "QS"是每个季度第一天为开始日期, "Q"是每个季度最后一天 number date 2013-12-31 51 2014-03-31 73 2014-06-30 96 2014-09-30 136 2014-12-31 148
按年统计数据
print(df.resample('AS').sum()) # "AS"是每年第一天为开始日期, "A是每年最后一天 number date 2013-01-01 51 2014-01-01 453 2015-01-01 743 2016-01-01 1552 2017-01-01 92
- 关于日期的类型,按参考下图所示来选择合适的分期频率:
按日期统计后,按年或季度或月份显示
按年统计并显示
print(df.resample('AS').sum().to_period('A')) # 按年统计并显示 number date 2013 51 2014 453 2015 743 2016 1552 2017 92
按季度统计并显示
print(df.resample('Q').sum().to_period('Q').head()) # 按季度统计并显示 number date 2013Q4 51 2014Q1 73 2014Q2 96 2014Q3 136 2014Q4 148
按月度统计并显示
print(df.resample('M').sum().to_period('M').head()) # 按月度统计并显示 number date 2013-10 10 2013-11 14 2013-12 27 2014-01 16 2014-02 4
按日期和其他条件组合分组
要按日期和其他条件组合分组,可以使用 Pandas 的 groupby
方法。具体来说,
- 首先使用
set_index
按照日期将DataFrame
转换为时间序列格式, - 再使用 groupby 按照其他条件进行分组。
以一个包含日期、城市和销售额的示例数据集为例:
import pandas as pd data = { 'date': ['2022-01-01', '2022-01-01', '2022-01-02', '2022-01-02'], 'city': ['Shanghai', 'Beijing', 'Shanghai', 'Beijing'], 'sales': [1000, 2000, 1500, 2500] } df = pd.DataFrame(data) df['date'] = pd.to_datetime(df['date'])
现在我们可以使用 set_index 将 date 列设置为索引,从而转换为时间序列格式:
df = df.set_index('date')
此时 df 的索引变成了日期类型。接下来,我们可以使用 groupby 方法按照 city 和日期进行分组:
grouped = df.groupby([pd.Grouper(freq='D'),'city'])
这里 [pd.Grouper(freq='D'),'city'] 表示按照天为频率(日历日),并按照城市进行分组。现在,我们可以对分组后的数据进行聚合操作,如求和等:
result = grouped.sum()
这样,我们就可以得到按照日期和城市进行分组后的销售额总和。
DataFrame 新增列的五种方法
分组和统计个数
根据不同列分组,分组后对不同列使用不同的聚合函数
对所有列求和,求平均,统计
import pandas as pd student = pd.read_excel(".../Students.xlsx",index_col="ID") temp = student[["Test_1","Test_2","Test_3"]] student["total"] = temp.sum(axis=1)#axis 0为列,1为行 student["avg"] = temp.mean(axis=1) print(student)
注意: 该操作自动忽略了空值进行均值
案例
【例】与书本不同,本节利用tushare读取招商银行股票数据,并进行 Pandas 基本操作。tushare为金融数据分析提供便捷、快速的接口,与投研和量化策略无缝对接 数据丰富 拥有丰富的数据内容,如股票、基金、期货、数字货币等行情数据,公司财务、基金经理等基本面数据。tushare是第三方库,因此,在首次使用时,需要通过pip安装。
import pandas as pd import tushare as ts import datetime ZSYH = ts.get_hist_data('600036', '2020-08-31', '2020-09-11') ZSYH.head(3)
ZSYH.tail(3)
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16133754.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步