Python教程

Python数据分析易错知识点归纳(三):Pandas

本文主要是介绍Python数据分析易错知识点归纳(三):Pandas,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

三、pandas

不带括号的基本属性

df.index
df.columns
	注意可以直接赋值,如: df.columns = ['A', 'B', 'C']

df.values
df.shape  返回元组
df.size  总个数
df.dtypes
# 返回布尔值,表示对象是否为空
df.empty 

设置不隐藏

pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

df.info()

df.describe()

print(df.describe())
'''
              a         b
count  9.000000  5.000000
mean   2.777778  2.200000
std    1.201850  0.273861
min    1.000000  2.000000
25%    2.000000  2.000000
50%    3.000000  2.000000
75%    3.000000  2.500000
max    5.000000  2.500000
'''
print(df.describe(include=['object'])) #显示freq最高的对象
print(df.describe(include='all'))

df.idxmin() 返回各列最小值的行名,df.idxmax同理

df.sort_index()

asc_sorted_df = unsorted_df.sort_index()
desc_sorted_df = unsorted_df.sort_index(ascending=False)
col_sorted_df = unsorted_df.sort_index(axis=1)

df.sort_values()

注意:若前面没有=,一定要带inplace=True, 否则不起作用

col1_sorted_df = unsorted_df.sort_values(by='col1')
col1_col2_sorted_df = unsorted_df.sort_values(by=['col1', 'col2'])

# 实际过程中:若想取到排序之后的第一行行号
df_sort.index[0] 
# 或者使用df[col_name].idxmin()或df[col_name].idxmax()

df[col_name].value_counts()

#注意:1,只能用于Series;2.返回一个Series,按照出现频率按多到少排序,index为原value
print(data['a'].value_counts())

# 注意以下方法只适合目标value为0,1类型的数据
# 巧用value_counts()和groupby计算不同...类型...的比率
cp_count = data['cp'].value_counts()  # cp为胸痛类型  # 输出为Series
gr_cp_sum = data.groupby('cp')['target'].sum() # target为1表示患病,0表示不患病  # 输出为Series
print('不同胸痛类型的就诊者所患病的比率\n', round(gr_cp_sum / cp_count, 2))

df.reindex()与df.reindex_like()与df.rename()与df.reset_index()(重建索引)

# 注意不要被reindex的名字所迷惑,其功能类似于切片,如:取0,2,100行,'A', 'B', 'Z'列;不同之处是,可以是原df中不存在的行或列,生成新的df中,这里行或列为NaN
df_reindexed = df.reindex(index=[0,2,100], columns=['A', 'B', 'Z'])

# 若想重建索引,直接给df.index赋值即可
df.index = range(len(df))


df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3'])
df1 = df1.reindex_like(df2) # 必须确保df1和df2列明相同

# rename通过字典结构重建
print(df1.rename(columns={'col1':'c1','col2':'c2'},index ={0 :'apple',1 :'banana',2 :'durian'}))

# reset_index 将旧索引添加为列,并使用新的顺序索引----> 多用于使用多个字段groupBy聚合之后
df.reset_index()
daily_rental =  bikeDf_time.groupby(['year','month','day','weekday','day_type'])['count'].sum().reset_index()

df条件过滤

print(df[df.A > 0])  # A列大于0的值
# print(df[df['A'] > 0])  # 也可以这样写
'''
                   A         B         C         D
2020-01-01  0.105586 -0.173702  0.360643 -1.866179
2020-01-06  2.790227  0.053426 -1.123202  0.573211
'''

print(df[(df.A > 0) & (df.B < 0)])  # 多个条件过滤:需用小括号包裹,且只能用& | ~

# 注意这里与df[df.A > 0]的区别
print(df[df > 0])  # 获取所有大于0的值,小于0设为NaN
'''
                   A         B         C         D
2020-01-01  0.021760  0.467921       NaN  0.442172
2020-01-02       NaN       NaN       NaN       NaN
2020-01-03       NaN       NaN       NaN  0.421954
2020-01-04       NaN       NaN       NaN  0.254046
2020-01-05  0.970615  1.234028  1.920165  0.802954
2020-01-06       NaN       NaN       NaN       NaN
2020-01-07       NaN  0.292532       NaN       NaN
'''

# 使用isin()方法进行过滤
df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three', 'two']
print(df2[df2['E'].isin(['two', 'four'])])

# 字符串类型的模糊查询
copy2 = copy.loc[copy['业务员名称'].str.contains('张|赵')]

df删除列/se删除列(还有其它的?numpy怎么删?)

# list删除元素(三种方法: remove、del、pop)
li = ['A', 'B', 'C']
li.remove('B')
del li[1]
li.pop(2)  # 参数是下标

# numpy删除列(一种方法: delete)
a = np.arange(12).reshape(3, 4)
print('第一个数组:')
print(a)
print('未传递Axis参数。在插入之前输入数组会被展开。')
print(np.delete(a, 5))
print('删除第二列:')
print(np.delete(a, 1, axis=1))
'''
第一个数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
未传递Axis参数。在插入之前输入数组会被展开。
[ 0  1  2  3  4  6  7  8  9 10 11]
删除第二列:
[[ 0  2  3]
 [ 4  6  7]
 [ 8 10 11]]
'''

# DataFrame删除列(三种方法:drop、del、pop, 后面两种只能一个一个的删)
df.drop('A', axis=1, inplace=True)
df.drop(['A', 'B'], axis=1, inplace=True)
del df['A']
df.pop('A')

# Series删除某个index(三种方法:drop、del、pop, 后面两种只能一个一个的删)
se.drop(['A', 'B'], inplace=True)  # 注意这里不要带axis参数(只有axis=0,所以不用带)
del se['A']
se.pop('A')

df删除行、重复行

df = df.drop(0)  # 索引名0重复被一并删除

# 根据条件删除行
df.drop(data[data['A4']==0].index, inplace=True)

copy = sheet1_shee2_merge.drop_duplicates('业务员编码', inplace=False)  # 是直接在原来数据上修改还是保留一个副本

# 统计数据重复
print('sheet1订单号重复检查:')
print(sheet1Df['订单号'].duplicated().value_counts())
# 结果为series, index为False和True, 值分别为不重复和重复的数量

# 所有列的值一样视为重复
print(data.duplicated().value_counts())
data.drop_duplicates(inplace=True)

用字典创建series和dateframe的区别

前者:字典的key是创建index

后者:字典的key是创建columns

注意loc和iloc的区别

# 省略方式取列的方法
df['B']  # 取一列
df[['A', 'B']]  # 取多列

# 唯一可以省略方式取行的方法:必须使用冒号(其它方式使用loc或iloc)
df[2:4]  # 参数是行索引号,结果为2行(等同于df.iloc[2:4, :])
df['20220806': '20220808'] # 行名,结果为3行 (等同于df.loc['20220806': '20220808', :])

# loc方法(貌似行号不能非连续)(注意loc中的参数冒号都是取头又取尾,不管index是不是默认或数值型)
df.loc[:, ['A', 'C']]
df.loc['20220806']
df.loc['20220806': '20220808', ['A', 'C']]
df.loc['20220806', ['A', 'C']]
df.loc['20220806', 'A':'C']

# iloc方法(行索引和列索引都可以不连续)(注意iloc中的参数冒号都是取头不取尾)
df.iloc[2:4, 0:2]
df.iloc[[2, 4], [0, 2]]
df.iloc[1, 1]

df.loc['b':'e']  # 是包含e行的
df.iloc[1:4] # index从1到3,不包含4

缺失数据处理

df['one'].isnull()
df['one'].notnull()
df['one'].sum()  # 若有缺失数据(NaN),求和时视为0,这里不会报错

# 查看数据缺失情况
# 方法一
print(df.info())  
# 方法二(推荐)
print(df.isnull().sum())  # 生成一个Series
# 方法三:1表示不含缺失值,2表示含缺失值(notnull()结果只有True和False)
print(df.notnull().nunique())

df.fillna(0)
# 对某一列进行处理
df['A2'] = df['A2'].fillna(1)
df['A7'] = df['A7'].fillna(df['A7'].mean())
# 查看众数的方法
# 1表示不含缺失值,2表示含缺失值(notnull()结果只有True和False)
print(df.notnull().nunique())

# pad/fill          填充方法向前
# bfill/backfill   填充方法向后
df.fillna(method='pad')

df.dropna()  # 默认axis=0,按行删除,若一行中有NaN,删除该行
df.dropna(axis=1) # 按列删除
df.dropna(inplace=True, thresh=10) # thresh表示非NaN行数,小于此值就删除

# 利用方法replace
df.replace({1000: 10, 2000: 20})
data['chol'].replace(564,246,inplace=True)

数据分析空处理规则:

  • NaN -- 默认值(政策、法规、规范)

  • NaN -- 序列型用中位数(median)、数值型用均值(mean)、类别型用众数(mode, 注意其结果为Series, 需要加[0]) (序列型:如疾病的严重程度,一般分为轻1、中2、重度3,数字大小有严重等级关系)(类别型:如血型,一般分为A、B、O、AB四个类型,用1-4表示,数字大小没有等级关系)

    data['小区房屋出租数量'] = data['小区房屋出租数量'].fillna(data['小区房屋出租数量'].mean())
    data['地铁站点'] = data['地铁站点'].fillna(data['地铁站点'].median())
    data['出租方式'] = data['出租方式'].fillna(data['出租方式'].mode()[0])
    
  • NaN -- 向前、向后(数据波动有规律)

  • NaN -- replace(明显错误)

  • NaN -- 逼近值(拉格朗日opp、牛顿差值oop)

  • NaN -- 删除(少于5%,不一定)行、列 (利用参数thresh(有效数据的最低要求), 5%需要手动计算一下)

数据相关性

Pearson相关系数

  • |r|<=0.3 不存在线性相关
  • 0.3 < |r| < 0.5 低度线性相关
  • 0.5 < |r| <=0.8 显著线性相关
  • |r| > 0.8 高度线性相关

数据深度克隆

df.copy(deep=true)

df.pipe/df.apply/se.map

  • df.pipe与se.map的区别
def adder(ele1,ele2):
    return ele1+ele2

df=df.pipe(adder,20) # 方法1通过pipe调用操作函数,并设置叠加值
# df+=20 # 方法2直接将df叠加值即可,pandas最新管道用法
print('管道将DataFrame的所有元素叠加20:')


#通过map函数仅对指定列运算
myArray=np.random.randn(5,3)
print(myArray)
df = pd.DataFrame(myArray,columns=['col1','col2','col3'])
df=df['col1'].map(lambda x:x*100)
  • df.apply(aggfunc) axis = 0(默认),按列处理;axis=1,按行处理,将一行作为一个Series传入aggfunc中

  • se.map(aggfunc) 它是Series的函数,aggfunc只能传入一个参数

统计

df.pct_change()
df.cov(df2)
df.corr(df2)

分组聚合过滤

df.aggregate(np.sum)   # 可以简写为df.agg
df['A'].aggregate(np.sum)
df[['A','B']].aggregate(np.sum)
df['A'].aggregate([np.sum,np.mean])

# 分组
print(df.groupby('Team').groups)  # 注意df.groupby('Team')结果显示的是对象内存
grouped = df.groupby('Year')  # 其结果是一个元组(groupby_name, df_group),它可以用for进行遍历
#查看分组
print(grouped.get_group(2014)) # 获取某个组别数据

# 聚合(aggregate)  - 先分组,再聚合
# 使用numpy标准函数:若使用一个函数(且不带中括号),生成一个Series, 否则生成一个DataFrame,列名为函数名,如sum,mean
print(grouped['Points'].agg(np.mean))
print(grouped['Points'].agg([np.sum, np.mean, np.std]))

# 注意与上面的区别:上面生成一个Series, 字典方式和带中括号方式都是生成一个DataFrame
print(grouped['Points'].agg([np.mean]))  # 带中括号就会生成DataFrame
print(grouped.agg({'Points': np.mean}))

# 使用字典方式实现不同字段使用不用聚合函数(包含自定义函数)
# 注意这里的区别:groupby后直接agg,不用取某一个字段
df_gr = data.groupby('No').agg({'Close': cal_perc_fun, 'Volume': np.sum, 'High': np.amax, 'Low': [np.amin, np.amax] })  # 其中cal_perc_fun为自定义函数,也可以写成lambda函数
# 生成的df_gr字段,若没有一个字段多个函数,直接就是字段名;否者为复合字段名,为元组形式,如:
#MultiIndex([('Close','cal_perc_fun'),('Volume','sum'),('High','amax'),('Low','amin'),( 'Low','amax')])
# 取值方式:df_gr[('Low', 'amin')]

# 使用自定义函数
print(grouped['Points'].transform(lambda x: (x-x.mean())/x.std * 10))

# 过滤
print(df.groupby('Team').filter(lambda x: len(x) > 3)) # 返回三次以上参加的队伍

透视表

'''
step4:数据透视表操作,每个地区的业务员分别赚取的利润总和与利润平均数
'''
pivot_table = pd.pivot_table(sheet1_shee2_merge, index='地区名称', columns='业务员名称', values='利润', aggfunc=[np.sum, np.mean])
print('每个地区的业务员分别赚取的利润总和与利润平均数透视表:')
print(pivot_table)
print('********************************************************************')
'''
         sum                               ...    mean                           
业务员名称    倪仲涛    刘仕祯    卞思宝    吴雯龙     尚庆龙  ...     陈国聚   陈恩泽     高鹏     麦豪    黄佳成
地区名称                                       ...                                   
上海       NaN    NaN    NaN    NaN     NaN  ...     NaN  30.0  200.0  780.0  360.0
北京       NaN    NaN  420.0    NaN     NaN  ...     NaN   NaN    NaN    NaN    NaN
广州     300.0  170.0    NaN    NaN  1200.0  ...     NaN   NaN    NaN    NaN    NaN
深圳       NaN    NaN    NaN  330.0     NaN  ...  3200.0   NaN    NaN    NaN    NaN

[4 rows x 40 columns]
'''

crosstab

# 分布统计不同赛季输和赢的场数
knicks2 = pd.crosstab(knicks.season, knicks.win)
'''
win      L   W
season        
07-08   59  23
08-09   50  32
09-10   53  29
10-11   40  42
11-12   30  36
'''

哑变量

# 当值只有两类时
df['win_flag'] = df['win'].map({'L': 0, 'W': 1})

# 当值有多类时
def dummies(data, col_name_list):
    for col_name in col_name_list:
        # 类别大于2类的列做哑变量处理
        if len(data[col_name].value_counts()) > 2:
            tempDf = pd.get_dummies(data[col_name], prefix=col_name)
            data = pd.concat([data, tempDf], axis=1)
            data.drop(col_name, axis=1, inplace=True)
    return data

按区间切割赋值

bins = [0, 1932, 2345, 10000]
groups = ['低', '中', '高']
Dataframesale['分组'] = pd.cut(df['利润'], bins, labels=groups)
print(df)
print('********************************************************************')
'''
  地区名称      利润 分组
0   上海  1970.0  中
1   北京  1820.0  低
2   广州  2720.0  高
3   深圳  8330.0  高
'''

连接

rs = pd.merge(left, right, on='id')
rs = pd.merge(left, right, on=['id', 'subject_id'])

# 若连接的表之间有相同字段,可以通过参数suffixes加后缀,默认为['_x', '_y']
df_mer = pd.merge(df_2015, df_2016, on=['Month', 'Day', 'Hour'], suffixes=['_2015', '_2016'])

rs = pd.merge(left,right,on='subject_id',how='left')
# left/right/outer(全连接)/inner 默认为inner

合并

ignore_index设置为True生成连续索引

rs = pd.concat([one,two], keys=['x','y'], ignore_index=True)
#使用keys把特定的键与每个碎片的DataFrame关联起来
#ignore_index设置为True生成连续索引,一般在axis=0时使用

rs = pd.concat([one,two], axis=1) #横向合并  注意多个df一定要用[]

rs = one.append(two)
rs = one.append([two, one, two])

文件IO

df = pd.read_csv('temp.csv', index_col=['S.No']) # 使用某列作为索引
df = pd.read_csv('temp.csv', dtype={'Salary': np.float64}) # 更改某列的数据类型
# 使用header指定标题行,使用names自定义列名
df = pd.read_csv('temp.csv', names=['a', 'b', 'c'], header=0) 
# skiprows跳到指定行数开始显示
df = pd.read_csv("temp.csv", skiprows=2)
这篇关于Python数据分析易错知识点归纳(三):Pandas的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!