Pandas基础
前言
版本问题:保证pandas库的版本不低于1.2.0,确认已经安装了 xlrd, xlwt, openpyxl 这三个包。
且当pandas版本为1.2.x时,xlrd版本不得高于 2.0.0
文件操作
文件读取
- csv:
pd.read_csv()
- excel:
pd.read_excel(<file_path>, sheet_name=<sheetN>)
通过指定sheet_name
来读取excel的某一个sheet
如果事先不知道sheet, 也可以通过my_data=pd.ExcelFile(<'a_excel.xls'>)
来读取指定sheet的excel文件- 先查看sheet:
my_data.sheet_names
来查看有多少个sheet - 然后开始读取
for sheet in my_data.sheet_names: df = pd.read_excel(<'file_name'>, )
- 先查看sheet:
- txt:
pd.read_table()
在读取txt
文件时,经常遇到分隔符非空格的情况,参数sep=<' \|\|\|\|'>
使得我们能够以正则表达式的语法自定义分割符号,这里设定的分隔符为||||
- 公共参数:
-
header:Bool=None
: 表示第一行不作为列名 -
index_col=<['col1', 'col2']>
: 表示把某一列或几列作为索引 -
usecols=<['col1', 'col3']>
: 表示读取列的集合,默认读取所有列,但是当文件较大的时候,可能需要一次读取一部分 -
parse_dates=<['col5']>
: 表示需要转化为时间的列 -
nrows:int=<2>
: 表示读取的数据行数
-
数据写入
-
<df_csv>.to_csv(<'a_csv_file'>, index=False)
: 将<df.csv>数据写入到<a_csv_file>中去,为了去除索引,一般将参数index
设置为False
,特别当索引没有特殊意义时。to_csv()
可以将数据保存为txt
文件,并且可以通过参数sep=<'\t'>
自定义分隔符,这里分隔符是常用的制表符\t
-
<df_txt>.to_excel(<'a_excel_file'>, index=False
在安装了tabulate
包的情况下,可以将表格快速转换为markdown
和latex
语言,当然转换后还需要打印或导出 df_csv.to_markdown()
df_csv.to_latex()
基本数据结构
pandas
中具有两种基本的数据存储结构,存储一维values
的Series
和存储二维values
的DataFrame
,在这两种结构上定义了很多的属性和方法
Series
Series
一般由四个部分组成:
* 序列的值data
* 索引index=<pd.Index(['id1', 20, 'third'], name='my_idx')>
: 索引可以指定它的名字,默认为空。索引是最重要的概念之一。
* 存储类型dtype=<object>
: object
代表一种混合类型,纯字符串序列默认为混合类型的序列,也可以用string
类型存储
* 序列的名字name
通过后缀<any_series>.values
的方式可以获取series
的data
信息,其他三个和上面一样。
利用<any_series>.shape
可以获取series的长度。
通过[<index_item>]
的方式可以取出单个索引对应的值。
DataFrame
在series
的基础上增加了列索引,二维表格型数据。
# 构造方式1
data = [[1, 'a', 1.2], [2, 'b', 2.2], [3, 'c', 3.2]]
df = pd.DataFrame(data = data,
index = ['row_%d'%i for i in range(3)],
columns=['col_0', 'col_1', 'col_2'])
# 构造方式2
df = pd.DataFrame(data = {'col_0': [1,2,3], 'col_1':list('abc'),
'col_2': [1.2, 2.2, 3.2]},
index = ['row_%d'%i for i in range(3)])
# ->
col_0 col_1 col_2
row_0 1 a 1.2
row_1 2 b 2.2
row_2 3 c 3.2
同样可以通过[<col_name>]
的方式来取出对应元素,可以通过.T
转置
df['col_0'] # -> dtype:Series
df[['col_0', 'col_1']] # -> dtype:DataFrame
df['col_0']['row_0'] # -> 1
取出相应的属性
df.values # -> 取出具体的data
df.index #-> 取出行的名称
df.columns #-> 取出列的名称
df.dtypes #-> 取出值为相应列数据类型的series
# ->
col_0 int64
col_1 object
col_2 float64
dtype: object
df.shape #->返回长宽索引
常用函数
在导入数据后,取前几列或者前几行df = df[df.columns[:7]]
: 取前7列df_demo = df[['Height', 'Weight']]
: 取出身高和体重列,返回一个200×2的DataFramedf.head(7)
, df.tail(7)
: 返回表或序列的前 n 行和后 n 行,默认为5
数据统计函数
df.info()
: 返回表的信息概况(如类型,行数,列数,值,数据类型,内存占用)df.describe()
: 返回表的数值列对应的主要统计量(如平均值,方差,最大值等)
如果需要更全面的数据统计,使用pandas-profiling
包
特征统计函数
sum, mean, median, var, std, max, min
等
df_demo.mean()
df_demo.max()
# 返回了Series数据,看起来像进行了转置
# ->
Height 163.218033
Weight 55.015873
dtype: float64
quantile
, count
, idxmax
分别返回分位数、非缺失值个数、最大值对应的索引。它们返回的都是标量,因此这三个又被称为聚合函数。
它们有公共参数axis
: 默认为0代表按列聚合,设置为1代表逐行聚合
df_demo.quantile(0.75)
# - : Series >
Height 167.5
Weight 65.0
Name: 0.75, dtype: float64
唯一值函数
对Seires
数据使用unique
和nunique
可以分别得到其唯一值组成的列表和唯一值的个数value_counts
可以得到去除重复后的值和其对应出现的频数,返回的是一个Series
数据
df['School'].unique()
# -> array(['Shanghai Jiao Tong University', 'Peking University', 'Fudan University', 'Tsinghua University'], dtype=object)
df['School'].nunique() #-> 4
df['School'].value_counts()
对于多个列组合的唯一值,可以使用方法.drop_duplicates(keep=< >)
,keep
参数有:
- 默认值
'first'
: 每个组合保留第一次出现的所在行 -
'last'
表示保留最后一次出现的所在行 -
False
表示把所有重复组合所在的行剔除,也就是说这个组合必须是独一无二的duplicated
返回是否为唯一值的布尔列表,keep
参数与上面一直,返回的序列中重复元素是True
。
这几个唯一值方法在Series
数据上也能用
替换函数
一般是对于Seires而言的。
映射替换
-
replace
方法:- 通过字典构造,或者传入两个列表进行替换
df['Gender'].replace({'Female':0, 'Male':1}).head() df['Gender'].replace(['Female', 'Male'], [0, 1]).head()
- 指定
method
参数为ffill
则为用前面一个最近的未被替换的值进行替换,指定参数为bfill
则使用后面最近的未被替换的值进行替换
s = pd.Series(['a', 1, 'b', 2, 1, 1, 'a']) s.replace([1, 2], method='ffill') s.replace([1, 2], method='bfill')
-
str.replace
方法:可以用正则表达式的语法 -
cat.codes
方法
逻辑替换
-
where
: 替换使得传入条件为False
的对应值 -
mask
: 替换使得传入条件为 True 的对应值
s = pd.Series([-1, 1.2345, 100, -50])
s.where(s<0, 100)
s.mask(s<0)
s_condition= pd.Series([True,False,False,True],index=s.index)
s.mask(s_condition, -50)
当它们当不指定替换值时,替换为缺失值
数值替换
有round
, abs
, clip
方法,分别表示按照给定精度四舍五入、取绝对值和截断
练一练: 使用两个逻辑替换
排序函数
- 值排序
sort_values
:df_demo.sort_values('Height', ascending=False).head()
: 默认ascending=True
代表升序(从小到大)df_demo.sort_values(['Weight','Height'],ascending=[True,False]).head()
: 多排序问题(如在体重相同的情况下,对身高进行排序,并且保持身高降序排列,体重升序排列) - 索引排序
sort_index
: 和值排序类似df_demo.sort_index(level=['Grade','Name'],ascending=[True,False]).head()
元素的值在索引中,此时需要指定索引层的名字或者层号,用参数 level 表示。另外,需要注意的是字符串的排列顺序由字母顺序决定
apply方法
apply常用于DataFrame的行迭代or列迭代,但性能不佳,只有在确实存在自定义需求的情况下才考虑使用。
参数:一般是一个以序列作为输入的函数,可以使用lambda表达式,还有一个参数axis
和聚合函数一样
df_demo.apply(lambda x:x.mean())
df_demo.apply(lambda x:(x-x.mean()).abs().mean())
# 返回一个序列中偏离该序列均值的绝对值大小的均值
# 也即L1均值
窗口对象
窗口是为了处理数值型数据而提供的概念,相当于是excel我们能够拖动的窗口的命令行版。
Pandas 提供了几种窗口函数,比如滑动函数(rolling)、扩张函数(expanding)和指数加权函数(ewm)
滑动窗口函数
要使用滑窗函数,就必须先要对一个序列使用.rolling
得到滑窗对象,其最重要的参数为窗口大小window
在得到了滑窗对象后,能够使用相应的聚合函数进行计算,也可以使用apply
传入自定义函数来计算,但传入值是对应窗口的Series
s = pd.Series([1,2,3,4,5])
roller = s.rolling(window = 3)
roller.mean() # ->
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
dtype: float64
roller.sum() # ->
0 NaN
1 NaN
2 6.0
3 9.0
4 12.0
dtype: float64
roller.cov(s2)
roller.corr(s2)
shift, diff, pct_change
是一组类滑窗函数,它们的公共参数为periods=n
,默认为1,分别表示取向前第n个元素的值、与向前第n个元素做差(与Numpy中不同,后者表示n阶差分)、与向前第n个元素相比计算增长率。这里的n可以为负,表示反方向的类似操作
s = pd.Series([1,3,6,10,15])
s.shift(2)
s.diff(3)
s.pct_change()
s.shift(-1)
s.diff(-2)
将其视作类滑窗函数的原因是,它们的功能可以用窗口大小为n+1的rolling方法等价代替
s.rolling(3).apply(lambda x:list(x)[0]) # s.shift(2)
s.rolling(4).apply(lambda x:list(x)[-1]-list(x)[0]) # s.diff(3)
def my_pct(x):
L = list(x)
return L[-1]/L[0]-1
s.rolling(2).apply(my_pct) # s.pct_change()
扩张函数
扩张窗口又称累计窗口,可以理解为一个动态长度的窗口,其窗口的大小就是从序列开始处到具体操作的对应位置,其使用的聚合函数会作用于这些逐步扩张的窗口上。
s = pd.Series([1, 3, 6, 10])
s.expanding().mean()
# ->
0 1.000000
1 2.000000
2 3.333333
3 5.000000
dtype: float64
指数加权函数
to be continue…
练习
练习好多 以后再说0v0