pandas学习总结

 总结一些pandas基础基础的用法,持续更新中。

查询数据

# 查询类型
df.dtypes

# 设置索引
df.set_index('ymd',inplace=True)

# 得到单个值(tianqi列,2018-01-03那行的数据)
df.loc['2018-01-03','tianqi']

# 得到series
df.loc['2018-03-03',['fengxiang','fengli']]
df.loc[['2018-01-04','2018-10-04'],'bWendu']

# 得到DataFrame
df.loc[['2018-01-04','2018-10-04'],['bWendu','yWendu']]

# 使用数值区间进行范围查询 注意:区间既包含开始,也包含结束
df.loc['2018-01-04':'2018-01-10',['bWendu','yWendu','aqiInfo']]

# 列index按区间
df.loc[['2018-01-01','2018-04-04'],'bWendu':'fengxiang']

# 行和列都按区间查询
df.loc['2018-01-04':'2018-01-10','bWendu':'fengxiang']

# 简单条件查询,最低温度低于-10度的列表
df.loc[(df['yWendu']<-10),:]

# 复杂条件查询
df.loc[(df['bWendu']>30) & (df['yWendu']>15) & (df['tianqi'] == '晴') & (df['aqiInfo'] == '优')]

# 直接写lambda表达式
df.loc[lambda df: (df["bWendu"]<=30) & (df["yWendu"]>=15), :]

# 使用df.query查询
df[(df['a'] > 0) & (df['b'] < 2)]
df.query("a>0 & b<2")

插入数据

# 1. 直接赋值
df['wencha'] = df.loc[:,'bWendu'] - df.loc[:,'yWendu']

# 2. df.apply方法
def get_wendutype(x):
    if x['bWendu']>33:
        return '高温'
    elif x['yWendu']<-10:
        return '低温'
    else:
        return '常温'        
# 注意需要设置axis==1,这里series的index是columns  DataFrame’s index (axis=0), DataFrame’s columns (axis=1)
df.loc[:,'wendutype'] = df.apply(get_wendutype,axis=1)

# 3. df.assign方法(同时添加多个列)
df.assign(
    bWendu_huashi = lambda x : x['bWendu'] * 9 / 5 + 32,
    yWendu_huashi = lambda x : x['yWendu'] * 9 / 5 + 32,
)

# 4. 按条件选择分组分别赋值
df['wencha_data'] = ''
df.loc[(df['bWendu'] - df['yWendu'] >= 10),'wencha_data'] = '温差大'
df.loc[(df['bWendu'] - df['yWendu'] < 10),'wencha_data'] = '温差正常'

汇总类统计

# 提取所有数字列统计结果
df.describe()

# 最高
df['yWendu'].max()

# 最低
df['bWendu'].min()

# 按值统计
df['bWendu'].value_counts()

# 唯一性去重
df['fengxiang'].unique()

# 协方差
df.cov()

# 相关系数
df.corr()

缺失值处理

"""
Pandas使用这些函数处理缺失值:
* isnull和notnull:检测是否是空值,可用于df和series
* dropna:丢弃、删除缺失值
  - axis : 删除行还是列,{0 or ‘index’, 1 or ‘columns’}, default 0
  - how : 如果等于any则任何值为空都删除,如果等于all则所有值都为空才删除
  - inplace : 如果为True则修改当前df,否则返回新的df
* fillna:填充空值
  - value:用于填充的值,可以是单个值,或者字典(key是列名,value是值)
  - method : 等于ffill使用前一个不为空的值填充forword fill;等于bfill使用后一个不为空的值填充backword fill
  - axis : 按行还是列填充,{0 or ‘index’, 1 or ‘columns’}
  - inplace : 如果为True则修改当前df,否则返回新的df
"""

# 检测空值
df.isnull()

# 筛选没有空分数的所有行
df.loc[df['分数'].notnull(),:]

# 删除掉全是空值的列
df.dropna(how='all',axis=1,inplace=True)

# 将分数为空的填充为0
df.loc[:,'分数'] = df['分数'].fillna(0)
df.fillna({'分数':0})

# 使用前面的有效值填充,用ffill:forward fill
df.loc[:,'姓名'] = df['姓名'].fillna(method='ffill')

数据排序

"""
Series的排序:  
***Series.sort_values(ascending=True, inplace=False)***  
参数说明:
* ascending:默认为True升序排序,为False降序排序
* inplace:是否修改原始Series

DataFrame的排序:  
***DataFrame.sort_values(by, ascending=True, inplace=False)***  
参数说明:
* by:字符串或者List<字符串>,单列排序或者多列排序
* ascending:bool或者List<bool>,升序还是降序,如果是list对应by的多列
* inplace:是否修改原始DataFrame
"""

# Series排序(降序)
df['aqi'].sort_values(ascending=False)

# DataFrame的排序
# 单列排序
df.sort_values(by='tianqi',ascending=False)

# 多列排序(分别指定升序和降序)
df.sort_values(by=['bWendu','yWendu'],ascending=[False,True])

字符串处理

"""
 使用方法:先获取Series的str属性,然后在属性上调用函数;
2. 只能在字符串列上使用,不能数字列上使用;
3. Dataframe上没有str属性和处理方法
4. Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似;
"""

# 字符串替换函数
df['yWendu'].str.replace('℃','')

# 判断是不是数字
df['tianqi'].str.isnumeric()

# 每次调用函数,都返回一个新Series
type(df['ymd'].str.replace('-','').str.startswith('201803'))
df['ymd'].str.replace('-','').str.slice(0,6)

# slice就是切片语法,可以直接用
df['ymd'].str.replace('-','').str[0:6]

# 方法1:链式replace
df["中文日期"].str.replace("年", "").str.replace("月","").str.replace("日", "")
# 方法2:正则表达式替换
df['中文日期'] = df['中文日期'].str.replace('[年月日]','')

DataFrame合并

"""
Pandas的Merge,相当于Sql的Join,将不同的表按key关联到一个表
### merge的语法:
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False,
         validate=None)  
* left,right:要merge的dataframe或者有name的Series
* how:join类型,'left', 'right', 'outer', 'inner'
* on:join的key,left和right都需要有这个key
* left_on:left的df或者series的key
* right_on:right的df或者seires的key
* left_index,right_index:使用index而不是普通的column做join
* suffixes:两个元素的后缀,如果列有重名,自动添加后缀,默认是('_x', '_y')
文档地址:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html

理解merge时数量的对齐关系

以下关系要正确理解:
* one-to-one:一对一关系,关联的key都是唯一的
  - 比如(学号,姓名) merge (学号,年龄)
  - 结果条数为:1*1
* one-to-many:一对多关系,左边唯一key,右边不唯一key
  - 比如(学号,姓名) merge (学号,[语文成绩、数学成绩、英语成绩])
  - 结果条数为:1*N
* many-to-many:多对多关系,左边右边都不是唯一的
  - 比如(学号,[语文成绩、数学成绩、英语成绩]) merge (学号,[篮球、足球、乒乓球])
  - 结果条数为:M*N
"""
# merge
ratings_users = pd.merge(left=df1,right=df2,on='key')

# inner join,默认
# 左边和右边的key都有,才会出现在结果里
pd.merge(left, right, how='inner')

# left join
# 左边的都会出现在结果里,右边的如果无法匹配则为Null
pd.merge(left, right, how='left')

# right join
# 右边的都会出现在结果里,左边的如果无法匹配则为Null
pd.merge(left, right, how='right')

# outer join
# 左边、右边的都会出现在结果里,如果无法匹配则为Null
pd.merge(left, right, how='outer')

数据的合并

"""
使用场景:
批量合并相同格式的Excel、给DataFrame添加行、给DataFrame添加列

concat语法:  
* 使用某种合并方式(inner/outer)
* 沿着某个轴向(axis=0/1)
* 把多个Pandas对象(DataFrame/Series)合并成一个。

concat语法:pandas.concat(objs, axis=0, join='outer', ignore_index=False)
* objs:一个列表,内容可以是DataFrame或者Series,可以混合
* axis:默认是0代表按行合并,如果等于1代表按列合并
* join:合并的时候索引的对齐方式,默认是outer join,也可以是inner join
* ignore_index:是否忽略掉原来的数据索引

append语法:DataFrame.append(other, ignore_index=False)
append只有按行合并,没有按列合并,相当于concat按行的简写形式  
* other:单个dataframe、series、dict,或者列表
* ignore_index:是否忽略掉原来的数据索引

参考文档:
* pandas.concat的api文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html
* pandas.concat的教程:https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html
* pandas.append的api文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.append.html
"""

# 默认的concat,参数为axis=0、join=outer、ignore_index=False***
pd.concat([df1,df2],ignore_index=True)

# 使用join=inner过滤掉不匹配的列***
pd.concat([df1,df2],ignore_index=True,join='inner')

# 使用DataFrame.append按行合并数据
df1 = pd.DataFrame([[1,2],[3,4]],columns=['A','B'])

# 可以一行一行的给DataFrame添加数据***
pd.concat(
    [pd.DataFrame([i],columns=['A']) for i in range(5)],
    ignore_index=True
)


groupby分组统计

# groupby:先对数据分组,然后在每个分组上应用聚合函数、转换函数

# 单个列groupby,查询所有数据列的统计
df.groupby(['A']).sum()

# 多个列groupby,查询所有数据列的统计,把索引列变为数据列
df.groupby(['A','B'],as_index=False).mean()

# 同时查看多种数据统计
df.groupby(['A']).agg([np.max,np.min,np.mean])

# 查看单列的结果数据统计
df.groupby('A')['C'].agg([np.max,np.min])

# 不同列使用不同的聚合函数
df.groupby('A',as_index=False).agg({'C':np.max,'D':np.min})

数据转换函数map、apply、applymap

"""
数据转换函数对比:map、apply、applymap:
1. map:只用于Series,实现每个值->值的映射;
2. apply:用于Series实现每个值的处理,用于Dataframe实现某个轴的Series的处理;
3. applymap:只能用于DataFrame,用于处理该DataFrame的每个元素;
"""

# map用于Series值的转换(传入字典)
stocks['中文公司1'] = stocks['公司'].map({"bidu": "百度","baba": "阿里巴巴"})

# map用于Series值的转换(传入函数)
stocks['中文公司2'] = stocks['公司'].map(lambda x: {"bidu": "百度","baba": "阿里巴巴"}[x])
或者
def a(x):
    return  {"bidu": "百度","baba": "阿里巴巴"}[x]
stocks['中文公司10'] = stocks['公司'].map(a)

"""apply用于Series和DataFrame的转换
* Series.apply(function), 函数的参数是每个值
* DataFrame.apply(function), 函数的参数是Series"""

# Series.apply
stocks['中文公司'] = stocks['公司'].apply(lambda x: {"bidu": "百度","baba": "阿里巴巴"}[x])

# DataFrame.apply
# 此时lambda函数的入参为Series
stocks.apply(lambda x: {"bidu": "百度","baba": "阿里巴巴"}[x['公司']],axis=1)  ## lambda x的x是一个Series,因为指定了axis=1所以Seires的key是列名,可以用x['列名']获取


"""applymap用于DataFrame所有值的转换"""

# 将这些数字取整数,应用于所有元素
sub_df.applymap(lambda x: int(x))

# 直接修改原df的这几列
stocks.loc[:,['收盘', '开盘', '高', '低', '交易量']] = sub_df.applymap(lambda x:int(x))



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值