一、Pandas 数据结构
Series :?列表?成
Series
时,
Pandas
默认?动?成整数索引,也可以指定索引
s1 = pd.Series(data = l) # pandas?动添加索引
s2 = pd.Series(data = l,index = list('abcdefhi'),dtype='float32') # 指定?索引
# 传?字典创建,key?索引
s3 = pd.Series(data = {'a':99,'b':137,'c':149},name = 'Python_score')
display(s1,s2,s3)
Series是一维的,DataFrame是二维的,多个Series公用索引,组成了DataFrame
# index 作为?索引,字典中的key作为列索引,创建了3*3的DataFrame表格?维数组
df1 = pd.DataFrame(data = {'Python':[99,107,122],'Math':[111,137,88],'En': [68,108,43]},# key作为列索引
index = ['张三','李四','Michael']) # ?索引
df2 = pd.DataFrame(data = np.random.randint(0,151,size = (5,3)),
index = ['Danial','Brandon','softpo','Ella','Cindy'],# ?索引
columns=['Python','Math','En'])# 列索引
columns=['Python','Math','En'],dtype=np.float16) # 列索引
二、数据查看
df.shape # 查看Data??? wFrame形状
df.head(n = 3) # 显示前N个,默认N = 5
df.tail() # 显示后n个
df.dtypes # 数据类型
df.info() # 比较详细信息
df.describe() # 描述:平均值、标准差、中位数、四等分、最大值,最小值
df.values # 值,返回的是NumPy数组
df.columns # 列索引
df.index # 行索引 0 ~ 99
三、数据输入与输出
1.csv
# 保存到当前路径下,?件命名是:salary.csv。csv逗号分割值?件格式
df.to_csv('./salary.csv',
sep = ';', # ?本分隔符,默认是逗号
header = True,# 是否保存列索引
index = True) # 是否保存?索引,保存?索引,?件被加载时,默认?索引会作为?列
# 加载
pd.read_csv('./salary.csv',
sep = ';',# 默认是逗号
header = [0],#指定列索引
index_col=0) # 指定?索引
pd.read_table('./salary.csv', # 和read_csv类似,读取限定分隔符的?本?件
sep = ';',
header = [0],#指定列索引
index_col=1) # 指定?索引,IT作为?索引
2、Excel
df.to_excel('./data.xls')
pd.read_excel('./data.xls',
index_col=0) # 第一列作为行索引
3、HDF5
HDF5
,可以存储不同类型数据的?件格式,后缀通常是
.h5
,它的结构是
层次性的。
?个
HDF5
?件可以被看作是?个组包含了各类不同的
数据集
。
# 保存到当前路径下,?件命名是:data.h5
df1.to_hdf('./data.h5',key='salary') # 保存数据的key,标记
df2.to_hdf('./data.h5',key = 'score')
pd.read_hdf('./data.h5',
key = 'salary')#获取指定的标记、key的数据
4、SQL
from sqlalchemy import create_engine # 数据库引擎,构建和数据库的连接
# 数据库连接
engine = create_engine('mysql+pymysql://root:123456@localhost/pandas?charset=utf8')
df2.to_sql('salary',engine,index=False) # 将Python中数据DataFrame保存到Mysql
df3 = pd.read_sql('select * from salary limit 50',con = engine)
df3
四、数据选取
获取数据
df['Python'] # 获取数据Series
df.Python # 属性,DataFrame中列索引,表示属性
df[['Python','En']] # 获取多列数据
标签选择
# 标签,就是行索引 location = loc 位置 df.loc[['A','F','K']]
df.loc[['A','C','F'],'Python']
位置选择
df.iloc[[0,2,4]]
df.iloc[0:4,[0,2]]
df.iloc[3:8:2] #从3到8每隔两个取一个
boolean索引
cond = df.Python > 80 # 将Python大于80分的成绩获取 df[cond]
cond = df.mean(axis = 1) > 75 # 平均分大于75,优秀,筛选出来 df[cond]
赋值操作
df['Python']['A'] = 150 # 修改某个位置的值
df['Java'] = np.random.randint(0,151,size = 10) # 新增加一列
df.loc[['C','D','E'],'Math'] = 147 # 修改多个人的成绩
cond = df < 60 df[cond] = 60 # where 条件操作,符合这条件值,修改,不符合,不改变
df.iloc[3::3,[0,2]] += 100
五、数据集成?
concat数据串联
pd.concat([df1,df2],axis = 0) # axis = 0变是行合并,行增加 ,axis = 1表示列增加
df1.append(df2) # append追加,在行后面直接进行追加?
数据插入
df1.insert(loc = 1, # 插入位置
column='C++', # 插入一列,这一列名字
value = np.random.randint(0,151,size = 10)) # 插入的值
# 对?的操作,使?追加append,默认在最后?,?法指定位置
# 如果想要在指定位置插??:切割-添加-合并
Join SQL风格合并
pd.merge(df1,df2,how = 'inner') # 根据共同name进行合并,两表合并,外键
pd.merge(df1,df2,how = 'outer') # 外合并,所有数据保留,不对应位置,填充了空数据
pd.merge(df1,df3,left_on='name',right_on='名字')
pd.merge(df5,score_mean,
left_index=True, # 数据合并根据行索引,对应
right_index=True) # 右边数据根据行索引,对应
六、数据清洗
# 重复数据删除 df.drop_duplicates() # 非重复数据,索引7和索引6重复数据,None和NaN一回事
df.dropna() # 空数据过滤
df.drop(labels=[2,4,6,8]) # 删除行,或者列,默认情况下删除行
df.drop(labels='color',axis = 1) # 删除指定的列,axis = 1
df.filter(items=['price']) # 参数意思,保留数据price
df['size'] = 1024 # 广播
df.filter(like = 'i') # 模糊匹配,保留了带有i这个字母的索引
df.filter(regex = 'e$') # 正则表达式,限制e必须在最后
df.filter(regex='e') # 只要带有e全部选出来
# 异常值,大于800,小于 100算作异常,认为定义的。根据实际情况。 cond = (a <=800) & (a >=100) a[cond]
七、数据转换
轴和元素转换
df.rename(index = {'A':'X','K':'Y'}, # 行索引
columns={'Python':'人工智能'}, # 列索引修改
inplace=True) # 替换原数据
df.replace(5,50,inplace=True)
df.replace([2,7],1024,inplace=True)
df.replace({0:2048,np.nan:-100},inplace=True)
df.replace({'Tensorflow':1024},-1024) # 指定某一列,进行数据替换
map映射元素转变
# map 只能针对一列,就是Series? ?
df['人工智能'].map({1024:3.14,2048:2.718,6:1108}) # 跟据字典对数据进行改变
def convert(x):
if x >= 1024:
return True
else:
return False
df['level'] = df['Tensorflow'].map(convert) # map映射,映射是Tensorflow中这一列中每一个数据,传递到方法中
df
apply映射元素转变
# 既可以操作Series又可以操作DataFrame
df['人工智能'].apply(lambda x : x + 100)
df.apply(lambda x : x + 1000) # apply对 所有的数据进行映射
def convert(x):
return (x.median(),x.count(),x.min(),x.max(),x.std())
df.apply(convert).round(1) # 默认操作列数据
df.apply(convert,axis = 1) # axis = 1,操作数据就是行数据
transform元素转变
index = np.random.permutation(10) # 返回打乱顺讯的索引 df.take(index)# 重排,索引打乱
df.take(np.random.randint(0,10,size = 20)) # 随机抽样20个数据
重排随机抽样哑变量?
哑变量(one-hot) # str类型数据,经过哑变量变换可以使用数字表示 pd.get_dummies(df2,prefix='',prefix_sep='') # 1表示,有;0表示,没有
八、数据重塑
# 多层索引MultiIndex
df2 = pd.DataFrame(np.random.randint(0,10,size = (20,3)),
columns=['Python','Math','En'],
index = pd.MultiIndex.from_product([list('ABCDEFHIJK'),['期中','期末']])) # 多层索引MultiIndex
?
df2.unstack().stack(level = 0)
?
df2.unstack(level = 1) # 将行索引变成列索引,-1表示最后一层
?df2.unstack(level = -1) # 将行索引变成列索引,-1表示最后一层
df2.stack() # 列变成行了
?
九、数学统计与方法
简单统计指标
df.count() # 统计非空数据数量
df.mean() # 平均值
df.median()) # 中位数
df['Python'].unique() # 去除重复数据
df['Math'].value_counts() # 统计出现的频次
df.quantile(q = [0,0.25,0.5,0.75,1]) # 百分位数
df.describe() #查看数值型列的汇总统计,计数、平均值、标准差、最?值、四分位数、最?值
索引标签、位置获取
df['Python'].argmax() # 返回最大值索引(返回第一个),argmin() # 最小值索引
df.idxmax() # 返回最大值的标签
更多统计指标
df.cumsum() # 累加和
df.cumprod() # 累乘和
df.cummin() # 累计最小值
df.std() # 标准差
df.var()# 方差
df.diff() # 差分,当前数据减去上一个的差值
df.pct_change().round(3) # 计算百分比变化
高级统计指标
df.cov() # 协方差:自己和别人计算
df.var() # 方差: 自己和自己计算
df.corr() # 相关性系数 -1 ~ 1
df.corrwith(df['En']) # 一列的相关性系数
十、排序
df.sort_index(axis = 0,ascending=False) # 降序,ascending为True升序
df.sort_values(by = 'Python',ascending=True) # 根据Python属性进行升序排列
df.sort_values(by = ['Python','Tensorflow'],ascending=True) # 先根据Python进行排序,如果相等在根据Tensorflow排序
df.nlargest(n = 5,columns='Python') # 根据Python进行排序,获取最大的5个数值
df.nsmallest(5,columns='Keras') # 根据Keras进行排序,获取最小的5个
十一、分箱操作
# 1、等宽分箱
pd.cut(df.Python,bins = 3)
# 指定宽度分箱
pd.cut(df.Keras,#分箱数据
bins = [0,60,90,120,150],#分箱断点
right = False,# 左闭右开
labels=['不及格','中等','良好','优秀'])# 分箱后分类
# 2、等频分箱
pd.qcut(df.Python,q = 4,# 4等分
labels=['差','中','良','优']) # 分箱后分类
?十二、分组聚合
分组
# 1、分组->可迭代对象
# 1.1 先分组再获取数据
g = df.groupby(by = 'sex')[['Python','Java']] # 单分组
for name,data in g:
print('组名:',name)
print('数据:',data)
df.groupby(by = ['class','sex'])[['Python']] # 多分组
# 1.2 对?列值进?分组
df['Python'].groupby(df['class']) # 单分组
df['Keras'].groupby([df['class'],df['sex']]) # 多分组
# 1.3 按数据类型分组
df.groupby(df.dtypes,axis = 1)
# 1.4 通过字典进?分组
m ={'sex':'category','class':'category','Python':'IT','Keras':'IT','Tensorflow':'IT','Java':'IT','C++':'IT'}
for name,data in df.groupby(m,axis = 1):
print('组名',name)
print('数据',data)
分组聚合
df.groupby(by = 'sex')[['Python','Math']].max() # 数学Python根据性别分组,求解的最大值
# apply聚合结果,少
df.groupby(by = ['sex','class'])[['Python','En']].apply(np.mean).round(1)
# transform 计算,返回的结果,还是DataFrame长度
df.groupby(by = ['sex','class'])[['Python','En']].transform(np.mean).round(1)
def _mean(x): #自己定义求平均值方法
return np.round(x.mean(),1)
df.groupby(by = ['sex','class'])[['Python','En']].transform(_mean)
分组聚合agg
# 分组后调?agg应?多种统计汇总
df.groupby(by = ['class','sex'])[['Tensorflow','Keras']].agg([np.max,np.min,pd.Series.count])
df.groupby(by = ['sex','class']).agg([('平均值',np.mean),('最大值',np.max),('最小值',np.min)])
# 分组后不同属性应?多种不同统计汇总
df.groupby(by = ['class','sex'])[['Python','Keras']].agg({'Python':[('最?值',np.max),
('最?值',np.min)], 'Keras':[('计 数',pd.Series.count),('中位数',np.median)]})
透视表
透视表也是?种分组聚合运算
df.pivot_table(values=['Python','Math','En'], # 要’透视‘值
index = ['sex','class'], # 索引,根据什么进行’透视‘ == 分组
aggfunc={'Python':[('平均值',np.mean)],
'Math':[('最小值',np.min),('最大值',np.max)],
'En':[('标准差',np.std),('方差',np.var),('计数',np.size)]}).round(1)
df.groupby(by = ['sex','class']).agg({'Python':[('平均值',np.mean)],
'Math':[('最小值',np.min),('最大值',np.max)],
'En':[('标准差',np.std),('方差',np.var),('计数',np.size)]}).round(1)
十三、时间序列
时间戳操作
# 1、创建?法
pd.Timestamp('2020-8-24 12')# 时刻数据,具体点
pd.Period('2020-8-24',freq = 'M') # 时期数据,表示一段时间,频率
index = pd.date_range('2020.08.24',periods=5,freq = 'M') # 批量时刻数据
pd.period_range('2020.08.24',periods=5,freq='M') # 批量时期数据
ts = pd.Series(np.random.randint(0,10,size = 5),index = index) # 时间戳索引Series
# 2、转换?法
pd.to_datetime(['2020.08.24','2020-08-24','24/08/2020','2020/8/24'])
pd.to_datetime([1598582232],unit='s')
dt = pd.to_datetime([1598582420401],unit = 'ms') # 世界标准时间
dt + pd.DateOffset(hours = 8) # 东?区时间(北京时间)
dt + pd.DateOffset(days = 100) # 100天后?期
时间戳索引?
index = pd.date_range("2020-8-24", periods=200, freq="D")
ts = pd.Series(range(len(index)), index=index)
# str类型索引
ts['2020-08-30'] # ?期访问数据
ts['2020-08-24':'2020-09-3'] # ?期切?
ts['2020-08'] # 传?年?
ts['2020'] # 传?年
# 时间戳索引
ts[pd.Timestamp('2020-08-30')]
ts[pd.Timestamp('2020-08-24'):pd.Timestamp('2020-08-30')] # 切?
ts[pd.date_range('2020-08-24',periods=10,freq='D')]
# 时间戳索引属性
ts.index.year # 获取年
ts.index.dayofweek # 获取星期?
ts.index.weekofyear # ?年中第?个星期?
ts.index.dayofyear # ?年中第?天
时间序列常用方法
index = pd.date_range('8/1/2020', periods=365, freq='D')
ts = pd.Series(np.random.randint(0, 500, len(index)), index=index)
# 1、移动
ts.shift(periods = 2) # 数据向后移动2
ts.shift(periods = -2) # 数据前移
# ?期移动
ts.shift(periods = 2,freq = pd.tseries.offsets.Day()) # 天移动
ts.tshift(periods = 1,freq = pd.tseries.offsets.MonthOffset()) #?移动
ts.shift(periods=-5,freq=pd.tseries.offsets.MonthBegin())
# 2、频率转换
ts.asfreq(pd.tseries.offsets.Week()) # 天变周
ts.asfreq(pd.tseries.offsets.MonthEnd()) # 天变?
ts.asfreq(pd.tseries.offsets.Hour(),fill_value = 0) #天变?时,?少变多,
fill_value为填充值
# 3、重采样
# resample 表示根据?期维度进?数据聚合,可以按照分钟、?时、?作?、周、?、年等来作为?期维
度
ts.resample('2W').sum() # 以2周为单位进?汇总
ts.resample('3M').sum().cumsum() # 以季度为单位进?汇总
# 4、DataFrame重采样
d = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
'volume': [50, 60, 40, 100, 50, 100, 40, 50],
'week_starting':pd.date_range('24/08/2020',periods=8,freq='W')})
df1 = pd.DataFrame(d)
df1.resample('M',on = 'week_starting').apply(np.sum)
df1.resample('M',on = 'week_starting').agg({'price':np.mean,'volume':np.sum})
days = pd.date_range('1/8/2020', periods=4, freq='D')
data2 = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
'volume': [50, 60, 40, 100, 50, 100, 40, 50]})
df2 = pd.DataFrame(data2,
index=pd.MultiIndex.from_product([days, ['morning','afternoon']]))
df2.resample('D', level=0).sum()
|