Python 数据分析Pandas进阶

一.Series和DataFrame的简单数学运算

      1.Series的运算:

       有值的则相加,没值对照的相加的为nan;

      2.Dataframe的运算:

      dataframe之间的相加运算和Series一样,不同的是sum运算:

df3 = DataFrame([[1,2,3],[4,5,np.nan],[7,8,9]],index=['A','B','C'],columns=['c1','c2','c3'])

# sum不加参数默认算的是一列的总和,如果有nan则忽略;
# 可以理解为一列中每一行的值相加,认为是对行的操作,axis=0
df3.sum()
# sum中当axis=1时指的是一行的总和,其实是一行中每一列的值相加,也可以通理解为对列进行操作
df3.sum(axis=1)

#其他操作
df3.min()
# 通过describe来看一些详细的参数
df3.describe()

二.Series和DataFrame的排序

    1.Series的排序

    #创建一个Series

    s1 = Series(np.random.randn(10))

    查看索引: s1. index    查看索引对应的值:  s1.values

   # 默认为升序排序;当ascending为false时为降序排序
   # 按value值排序

   s2 = s1.sort_values(ascending=False) 

   # 按index值排序
  s2.sort_index()

  2.Dataframe的排序

    #创建一个DataFrame

   df1 = DataFrame(np.random.randn(40).reshape(8,5), columns=['A','B','C','D','E'])

   # 想按照df1的a列排序,

   #只对df1的a列单独排序
   df1['A'].sort_values()

  # 按照column来排序
  df2 = df1.sort_values('A')

  df2.sort_index()

三.重命名DataFrame的Index

  #创建一个Dataframe

 df1 = DataFrame(np.arange(9).reshape(3,3), index=['BJ','SH','GZ'], columns=['A','B','C'])

 #变换index的方法一: 

 因为Datafrane的index是一个Series,故赋值如下:

 df1.index = Series(['bj','sh','gz'])

 #变换index的方法二: 

# 通过str,upper将index大写
# 注意map函数的参数为一个函数
df1.index = df1.index.map(str.upper)

# 方法三:直接使用rename的方式进行修改,rename的参数后可以跟函数或字典
df1.rename(index=str.lower, columns=str.lower)

df1.rename(index={'BJ': 'beijing'}, columns={"A":'a'})

小插曲->map操作:

# 将list中每个元素转换为str
list1 = [1,2,3,4]
list2 = ['1','2','3','4']

[str(x) for x in list1]

list(map(str, list1))

因为map的参数只能为函数,所以可以自定义函数来进行index值得交换

#方法四:自定义函数,通过map,rename进行交换

# 自定义函数
def test_map(x):
    return x + '_ABC'

df1.index.map(test_map)

df1.rename(index=test_map)

三.DataFrame的merge操作

#merge操作要求需要有相同name得column

#创建df1,df2

df1 = DataFrame({'key':['X','Y','Z','X'], 'data_set_1':[1,2,3,4]})

df2 = DataFrame({'key':['X','B','C'], 'data_set_2':[4,5,6]})

pd.merge(df1,df2,on=None)

# on的意思是df1和df2两边必须都有这个column;
# how的意思是merge的方式,默认的方式是采用内连接

pd.merge(df1,df2, on='key',how='inner')

# 左连接,把左边的显示完全
pd.merge(df1, df2, on='key', how='left')

# 右连接,把右边的进行补全
pd.merge(df1,df2, on='key', how='right')

pd.merge(df1,df2, on='key', how='outer')

四.DataFrame的Concatenate和Combine操作

# concatenate连接串联  Combine结合联合

  Concatenate:

 #numpy中:

 arr1 = np.arange(9).reshape(3,3)

 # 按列进行连接串联
 np.concatenate([arr1,arr2],axis=1)

 # Series中的行concatenate
 s1 = Series([1,2,3], index=['X','Y','Z'])

 s2 = Series([4,5], index=['A','B'])

 # 如果要设置axis=1对列进行添加,则原本列中没有的值将会被填写为nan

 pd.concat([s1,s2])

 #Dataframe中得行concatenate

 pd.concat([df1,df2]) 

 Combine:

 #Serise操作:

 s1 = Series([2, np.nan, 4, np.nan], index=['A','B','C','D'])

 s2 = Series([1,2,3,4], index=['A','B','C','D'])

 # 会用s2去填充s1
 s1.combine_first(s2)

 s2填充s1的意思是,如果s2和s1相同的index的value有值的话,则用s2的值替代s1的值;

#df操作:

df1.combine_first(df2)

四.通过apply进行数据预处理

# 将A字段下对应的所有的value值都变为大写
# apply的参数为一个函数
df['A'] = df['A'].apply(str.upper)

# 把一组data中的column给split成3列
# strip()将头尾的空格去掉
l1 = df['data'][0].strip().split(' ')

因为apply的参数只能是函数,所以要构造一个函数进行拆分:

def foo(line):
    items = line.strip().split(' ')
    return Series([items[1], items[3], items[5]])

df_tmp = df['data'].apply(foo)

#新构造的三列的列名为:0,1,2

df_tmp = df_tmp.rename(columns={0:"Symbol", 1:"Seqno", 2:"Price"})

df_new = df.combine_first(df_tmp)

删除多余的一列时:

del df_new['data']

五.通过去重进行数据清洗
 先看读取数据的length,再将数据unique后看其length有没有减少

len(df)

# unique的作用是去掉重复的数据
len(df['Seqno'].unique())

观察长度有没有变化

# 如果这个数据在一列中存在,则显示重复,存在显示true,不存在显示false
df['Seqno'].duplicated()

# drop_duplicates删除为true的数据

#默认则是删除第一个
# keep参数为last的意思是如果有重复则保存最后一个
df.drop_duplicates(['Seqno'],keep='last')

六.时间序列的操作基础

导入库:

import numpy as np
import pandas as pd
from pandas import Series, DataFrame

from datetime import datetime
t1 = datetime(2009,10,20)

创建一个以时间为序列index的Series:

date_list = [
    datetime(2016,9,1),
    datetime(2016,9,10),
    datetime(2017,9,1),
    datetime(2017,9,20),
    datetime(2017,10,1)
]

s1 = Series(np.random.rand(5), index=date_list)

通过datetime的索引的访问值:

s1[datetime(2016,9,10)] 

s1['2016-9-10']

s1['20160910']

s1['2017-09']

s1['2016']

# 其中start,end参数和periods参数是互斥的关系
# freq参数是指的步长,默认是一天,freq为W,则为一周
# 一周默认是周日,若从周一开始,则可以:W-MON
# 产生的是一个DatetimeIndex的数据类型
date_list_new = pd.date_range('2016-01-01', periods=100, freq='5H')

# 产生index为时间序列的一个Series
s2 = Series(np.random.rand(100), index=date_list_new)

七.时间序列数据的采样和画图

选取时间范围:

t_range = pd.date_range('2016-01-01', '2016-12-31')

# randn是从标准正态分布中返回一个或多个的样本值
# rand是指从随机样本中随机的返回值
s1 = Series(np.random.randn(len(t_range)), index=t_range)

#按月份去采样的第一种方法:

# 按月份进行采集数据,得到每个月的数据
s1['2016-01'].mean()

#按月份去采样的第二种方法:

# 按照月份去采样
s1_month = s1.resample('M').mean()

# 填充数据
# ffill() 月份的数据往前填充
# bfill() 月份的数据往后填充 
s1.resample('H').bfill()

t_range = pd.date_range('2016-01-01','2016-12-31',freq='H')

stock_df = DataFrame(index=t_range)

stock_df['BABA'] = np.random.randint(80, 160, size=len(t_range))

stock_df['TENCENT'] = np.random.randint(30, 50, size=len(t_range)

#绘图

stock_df.plot()

# 显示图像
import matplotlib.pyplot as plt
plt.show()

注:这个操作很重要!

将日期分开为一周进行查看:

weekly_df = DataFrame()

weekly_df['BABA'] = stock_df['BABA'].resample('W').mean()

weekly_df['TENCENT'] = stock_df['TENCENT'].resample('W').mean()

八.数据分箱技术Binning

数据分箱,即对数据进行分段,进而进行分类;

# 设置分段
bins = [0,59,70,80,100]

# cut的第一个参数是要对哪些数据做分箱,第二个参数是分段的列表
score_cat = pd.cut(score_list, bins)

# 分段计数
pd.value_counts(score_cat)

分段时也可以对dataframe进行字符串的标识:

分段对dataframe的标识:

df = DataFrame()

df['score'] = score_list

# 通过util.testing生成随机的字符串
df['student'] = [pd.util.testing.rands(3) for i in range(20)]

# 把score按照定义的bins去cut
# 定义label的一个区间,为list
df['Categories'] = pd.cut(df['score'],bins, labels=['Low','OK','Good','Great'])

九.数据分组技术GroupBy

# 参数为要group的column,返回的类型是dataframeGroupby
g = df.groupby(df['city'])

# 显示出group
g.groups

# 具体看下某一个column下的group
# 相当于把刚才分组为BJ的组单独生成了一个dataframe
df_bj = g.get_group('BJ')

# 对一个dataframe可以其求平均值
# 对单个group的dataframe求平均值,返回的是一个Series
df_bj.mean()

# 对groupby的object求分组的平均值
# 对group求平均值返回的是一个dataframe
# 这个dataframe是由Series经过combine操作得来的
g.mean()

Group操作的本质 = Split操作 + apply操作 + Combine操作

# 可以把group得到的dataframe转换为list或者字典
# 返回的是dataframe
dict(list(g))['BJ']

对group进行for循环遍历,查看其中的结构:

# for循环访问group得到的
for name, group_df in g:
    print(name)
    print(group_df)

十.数据聚合技术Aggregation

#先得到一个由groupby分组后的obj

# g是一个group的obj
g =df.groupby('city')

# 通过agg方法传入想要聚合的函数,函数可以为系统函数,也可以为自定义的函数
g.agg('min') 

def foo(attr):
    return attr.max() - attr.min()

g.agg(foo)

# 也可以按照多个column来进行分类
g_new = df.groupby(['city', 'wind'])

# 多个column的话同样要传入多个参数
g_new.get_group(('BJ',3))

对group的数据进行遍历操作:

# 多个column的group进行遍历时,同样第一栏需要由多个接受的值
for (name_1,name_2), group in g_new:
    print(name_1,name_2)
    print(group)

注:透视表之类的操作将作为专门的栏目总结

猜你喜欢

转载自blog.csdn.net/qq_29027865/article/details/81664413