pandas-wiki Acemyzoe

pandas

Series

Series是由相同元素类型构成的一维数据结构,有序且有索引。

import pandas as pd
import numpy as np
# 创建
data1 = [1,2,3] # data为list(1D)
data1 = np.array([1,2,3]) # data为ndarray(1D)
index1 = ['a','b','c'] # 不指定index则生成默认数值索引range(0, data.shape)
series1 = pd.Series(data=data1, index=index, name='series')

data2 = {'a':1,'b':2,'c':3} # data为dict
data2 = pd.Series([1,2,3], index = ['a','b','c']) # data为series
index2  = ['a','b','m'] # 额外提供index,进行重索引,缺失项填充NaN(not a number)
series2 = pd.Series(data=data2)

series.index # 索引
series.name # 名称
series.values # 值
series.dtype # 元素类型

# 查找
series[0] # scalar, 返回一个标量
series.loc['b'] # 单索引,返回一个值
series.iloc[1] # scalar, 返回一个值

series[0:2] # 范围,左闭右开,返回Series切片
series.loc['a':'c'] # 范围,注意:左闭右闭,返回Series切片
series.iloc[0:2] # 范围,左闭右开,返回Series切片

series[[0,2]] # 列表,返回Series切片
series.loc[['a','c']] # 列表,返回Series切片
series.iloc[[0, 2]] #列表,返回Series切片

# 改值
s = series.copy() # 深拷贝
s.loc['a'] = 10
s.loc['a':'c'] = [10, 4, 5]
'''
Series.replace(to_replace=None, value=None, inplace=False)
to_replace:要修改的值,可以为列表;
value:改为的值,可以为列表,与to_repalce要匹配;
inplace:是否在原地修改;
'''
s.replace(to_replace=10, value=100, inplace=False)
# 改索引
s.index = ['a','e','f']
s.rename(index = {'e':'b'}, inplace = False)
# 增
s.loc['d'] = 4 
s1 = pd.Series([22, 33], index=['a', 'g'])
s.append(s1, ignore_index=False) # 增加多行
# 删
del s['d']
s.drop(['a','c'])

DataFrame

DataFrame由具有共同索引的Series按列排列构成(2D)。

# 创建
data1 = [[1,2,3],
       [4,5,6]] # data为list of list(2D)
data1 = np.array([[1,2,3],[4,5,6]]) # data为ndarray(2D)

data2 = {'A':[1,4],'B':[2,5],'C':[3,6]} # data为dict of (ndarray(1D) or list(1D))

data3 = {'A':{'a':1,'b':4},'B':{'a':2,'b':5},'C':{'a':3,'c':6}} # data为dict of (Series or dict)

index = ['a','b']
columns = ['A','B','C']
df = pd.DataFrame(data=data1,index=index,columns=columns)
df.columns  # 列索引,由Series的name构成

# 由文件创建
pd.read_csv(filepath_or_buffer, sep=',', header='infer', names=None,index_col=None, encoding=None)
'''
filepath_or_buffer:路径和文件名不要带中文;
sep: csv文件数据的分隔符,默认是',';
header:如果有列名,那么这一项不用改;
names:如果没有列名,那么必须设置header = None,names为需要传入的列名列表,默认生成数值索引;
index_col:list of (int or name),传入列名的列表或者列名的位置,选取这几列作为索引;
encoding:文档编码,中文encoding = 'gbk'。
'''

# 查
'loc基于索引,iloc基于位置'
df['A'] # 列操作,单列索引,返回Series
df[['A','C']] # 列操作,列索引列表,返回DataFrame
df[0:1]  # 行操作,位置范围,返回DataFrame

df.loc['b','B'] # 返回单一值,因为两维都是单索引
df.iloc[1, 1] # 返回单一值,因为两维都是scalar

df.loc['a':'b', 'B'] #返回Series,如果只有一维是单索引
df.iloc[0:2,1]  # 返回Series,如有一果只维是scalar

df.loc[['a','b'], ['A','B']] #返回DataFrame
df.iloc[[0, 1], [0, 2]] # 返回DataFrame

# 改值
df1 = df.copy()
df1.loc['a','A'] = 10 #修改单值
df1.loc[:, 'A'] = [100, 200]  #修改单列
df1.loc[:, ['A','B']] = [[1,2],[3,4]]  #修改多列
df1.replace(to_replace=10, value=2, inplace=False)
# 改索引
df1 = df.copy()
df1.index = ['e','f'] # 索引类似于tuple,必须全改,不能切片修改
df1.columns = ['E','F','G']
df1.rename(index={'e':'b'},columns={'E':'A'}, inplace=False)
# 增
df1 = df.copy()
df1.loc['c'] = [7,8,9] # 增加一行
df1['H'] = [7,8] # 增加一列
df1 = pd.DataFrame([[22,33,44],[55,66,77]], index=['c','d'], columns=['A','B','C'])
pd.concat([df,df1], axis = 0 ) # 增加多行,确保列索引相同,行增加
df1 = pd.DataFrame([[22,33],[44,55]], index=['a','b'],columns=['D','E'])
pd.concat([df,df1], axis =1) # 增加多列,确保行索引相同,列增加
# 删
df1 = df.copy()
df1.drop(['a'],axis=0) # 删除多行
df1.drop(['A','C'], axis=1) # 删除多列

pd.merge

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False)
# concat函数只能根据索引对齐,而如果想在任意列上对齐合并,则需要merge函数,其在sql应用很多。
'''
left, right: 两个要对齐合并的DataFrame;
how: 先做笛卡尔积操作,然后按照要求,保留需要的,缺失的数据填充NaN;
	left: 以左DataFrame为基准,即左侧DataFrame的数据全部保留(不代表完全一致、可能会存在复制),保持原序;
	right: 以右DataFrame为基准,保持原序;
	inner: 交,保留左右DataFrame在on上完全一致的行,保持左DataFrame顺序;
	outer: 并,按照字典顺序重新排序;
on:对应列名或者行索引的名字,如果要在DataFrame相同的列索引做对齐,用这个参数;
left_on, right_on, left_index, right_index:
	on对应列名或者行索引的名字;
	index对应要使用的index,不建议使用。
sort: True or False,是否按字典序重新排序。
'''
import numpy as np
import pandas as pd
df1 = pd.DataFrame([[1,2],[3,4]], index = ['a','b'],columns = ['A','B'])
df2 = pd.DataFrame([[1,3],[4,8]], index = ['b','d'],columns = ['B','C'])
# 单纯的按照index对齐,推荐用concat方法。concat对重复列没有重命名,merge对重复列会重命名。
pd.merge(left=df1, right=df2, how='inner' ,left_index=True, right_index=True)
pd.concat([df1, df2], join='inner', axis =1)  

'on'
#对于'B'列:df1的'b'行、df2的'd'行,是相同的,其他都不同。 
pd.merge(left=df1, right=df2, how='inner', on=['B']) 
# df1的'A'列'b'行,df2的'C'列'd'行是相同的,其他都不同。
pd.merge(left=df1, right=df2, how='inner',left_on=['A'] ,right_on=['C'])
'how'
# 保持左侧DataFrame不变,用右侧来跟它对齐,对不上的填NaN。
pd.merge(left=df1, right=df2, how='left', on=['B'])

pd.MultiIndex

多层索引

data = [('a','one'),('a','two'),('b','one')]
index = pd.MultiIndex.from_tuples(data, names=['name1','name2'])
s = pd.Series([1,2,3], index = index)
index.set_names('new_name_1',level=0)
new_name_1  name2
a      one      1
       two      2
b      one      3
dtype: int64
df.swaplevel(axis=1)  # 交换列索引顺序

pd.to_datetime

将参数转换为日期时间。

import pandas as pd
print(pd.to_datetime('20200101', format='%Y%m%d', errors='ignore'))
df = pd.DataFrame({'year': [2015, 2016],
                   'month': [2, 3],
                   'day': [4, 5]})
print(pd.to_datetime(df))

行列~index

import numpy as np
import pandas as pd
data = [[1,2,3],[4,5,6]]
index = ['a','b']
columns = ['A','B','C']
df = pd.DataFrame( data=data,index=index,columns=columns)
'列转化为行索引'
df.set_index('A', drop=True, append=False) #单列转化为行索引,列名作为索引的名字
df.set_index(['A','B'], drop=True, append=False) # 列名的列表
df.set_index(['A','C'], drop=False, append=False) # drop = False, 保留原列
df.set_index(['A','C'], drop=False, append=True) # append = True, 保留原索引

df.set_index(keys=[['c','d']], append=False)# append为False,实现了改索引功能
# 元祖的列表建立多层索引
list_tuple = [('e','f'),('g','h')]
df1.set_index(keys = [list_tuple],append=False)

'行索引转化为列'
df1 = df.set_index(['A'], drop=True, append=True)
# df1.reset_index(level = 'A', drop = False)
df1.reset_index(level=1, drop=False) #单行索引

数值运算

import numpy as np
import pandas as pd
df1 = pd.DataFrame([[1,2],[3,4]], index=['a','b'],columns=['A','B'])
df2 = pd.DataFrame([[3,4],[5,6]], index=['b','c'],columns=['B','C'])
s1 = pd.Series([1,2], index=['A','B'], name='A')
df1 + df2   # df1的'B','b'和df2的'B','b'对上了,其他位置都至少有一个缺失值,此时填NaN
df1 + s1  # +号默认将Series的index与DataFrame的columns对齐,然后以DataFrame的index为index,纵向复制构造一个DataFrame。
df1.add(s1, axis='columns')  # 和+号功能相同,和列匹配,行扩展
s2 = pd.Series([1,2], index =['a','B'])
df1.add(s2, axis='index') # s2被转化为:以DataFrame的columns为columns,横向复制。和行匹配,列扩展
'''
-, ×, /, //,%, **
sub(), mul(), div(), floordiv(), mod(), pow()
'''
df1.abs() # 绝对值
# cum**()累计运算,从开始到当前数据结束获取一个值
df1.cummin()  # 默认为沿index,列的最小值
df1.cumsum(axis = 'columns')  # 按行累计求和
df1.clip(1,3)  # 将数据裁剪到一定范围内

数值统计运算

import numpy as np
import pandas as pd
df = pd.DataFrame([[1,2],[3,5]], index=['a','b'],columns=['A','B'])
df.sum() # 默认按列加
df.sum(axis='columns')
df.mean() # 均值
df.std() # 标准差
df.var() # 方差
# max(), min(), median()-最大、最小、中值
# cov(),corr()-协方差、相关系数

category类别类型

import numpy as np
import pandas as pd
c = pd.Categorical([2,1,1,3], ordered=True) 
c = pd.Categorical([2,1,1,3], categories=[3,2], ordered=True)
# 转换为类别类型
s = pd.Series([2,1,1,3])
s = s.astype('category') 
# 类别类型是序列形式,可以采用[]来查看,不支持.loc[]和.iloc[]。
# 改增删
c1 = c.copy()
c1.set_categories([2,4,5], ordered=True, inplace=True) # 删除了旧类别 1,增加新类别4、5

离散化

import numpy as np
import pandas as pd
s = pd.Series(range(0,5))
pd.cut(s, 3)   # 可以看到一共3个类别,类别形式为区间形式(]
pd.cut(s, 3, labels=['a','b','c'])
pd.cut(s,[0,2.5,4], right=False)  # 左闭右开,不包括4,所以4不属于任何一类别
pd.qcut(s, q = [0.0, 0.25, 0.5, 0.75, 1.0]) # 安装分位数q也来定义分隔点,而不是按照给定值