数据分析处理库(Pandas)

数据分析处理库(Pandas)

一、数据预处理

数据读取

pd.read_csv('数据所在的路径')
df.head(10) # 展示前10条数据,如果不填10,默认前5条
df.tail() # 展示后几条数据,默认后5条

DataFrame结构

df.info() # 用于打印当前读取数据的部分信息,包括数据样本规模、每列特征类型与个数、整体的内存占用等。
# 返回索引
df.index
# 拿到每一列特征的名字
df.columns
# 每一列的类型,其中object表示Python中的字符串
df.dtypes
# 直接取得数值矩阵
df.values

创建DataFrame

.iloc(): 用位置找数据
.loc(): 用标签找数据
DataFrame是通过读取数据得到的,如果想展示某些信息,也可以自己创建,最简单的方法是创建一个字典结构,其中key表示特征名字,value表示各个样本的实际值,然后通过pd.DataFrame()函数来创建。

data = {'country':['China', 'America', 'India'],
    'population':[14, 3, 12]}
df_data = pd.DataFrame(data)

在用Notebook执行代码的时候,如果数据量过多,读取的数据不会全部显示,而是会隐藏部分数据,这时可以通过设置参数来控制显示结果。
下面是几个常用的设置:

# 注意这个是get,相当于显示当前设置的参数
pd.get_option('display.max_rows')

# 这回可是set,就是把最大显示限制成6个
pd.set_option('display.max_rows', 6)
# Series相当于二维数据中某一行或一列
pd.Series(index = range(0, 100))

# 默认最大显示的列数
pd.get_option('display.max_columns')

pd.set_option('display.max_columns', 30)
pd.DataFrame(columns = range(0, 30))

Series操作

Series是什么呢?简单来说,读取的数据都是二维的,也就是DataFrame;如果在数据中单独取某列数据,那就是Series格式了,相当于DataFrame是由Series组合起来的。

创建Series得方法:

data = [10, 11, 12]
index = ['a', 'b', 'c']
s = pd.Series(data = data, index = index)

改数值:

s1.replace(to_replace = 100, value = 101, inplace = True)

replace函数中的inplace项,如果设置inplace=False,就是不将结果赋值给变量,只相当于打印操作;如果设置inplace=True,就是直接在数据中执行实际变换,而不仅是打印操作。

不仅可以改数值,还可以改索引:

s1.rename(index = {'a':'A'},inplace = True)

增至操作:

data = [100,110] 
index = ['h','k'] 
s2 = pd.Series(data = data,index = index) 
s3 = s1.append(s2) 
s3['j'] = 500

重置索引:在append函数中指定ignore_index = True

二、数据分析

统计分析

先用字典结构创建一个简单的DataFrame,既可以传入数据,也可以指定索引和列名:

 df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], index = ['a', 'b'], columns = ['A', 'B', 'C'])
# 默认是对每列计算所有样本操作结果,相当于df.sum(axis = 0)
df.sum()
# 也可以指定维度来设置计算方法
df.sum(axis = 1)
# 观察所有样本的情况
df.describe()

df = pd.read_csv('titanic.csv')
# 协方差矩阵
df.cov()
# 相关系数
df.corr()
# 统计该列所有属性的个数
df['Sex'].value_counts()
# 指定顺序,让少的排在前面
df['Sex'].value_counts(ascending = True)
# 指定划分成几个组
df['Age'].value_counts(ascending=True, bins=5)
# 用cut函数分组
ages = [15, 18, 20, 21, 22, 34, 41, 52, 63, 79]
bins = [10, 40, 80]
bins_res = pd.cut(ages, bins)
# 查看当前分组结果
bins_res.codes
# 各组总共人数
pd.value_counts(bins_res)

# 分成年轻人、中年人、老年人3组
pd.cut(ages, [10, 30, 50, 80])
# 可以自己定义标签
group_names = ['Yonth', 'Mille', 'Old']
pd.value_counts(pd.cut(ages, [10, 20, 50, 80], labels=group_names))

pivot数据透视表

df = pd.read_csv('titanic.csv')
df.pivot_table(index='Sex', columns='Pclass', values='Fare')

其中Pclass表示船舱等级,Fare表示船票的价格,这里表示按乘客的性别分别统计各个舱位购票的平均价格。index指定了按照什么属性来统计,columns指定了统计哪个指标,values指定了统计的实际指标值是什么。看起来各项参数都清晰明了。

# 统计各个船舱的最大票价,aggfunc来明确结果的含义。
df.pivot_table(index='Sex', columns='Pclass', values='Fare', aggfunc='max')

# 按照年龄将乘客分为成年组和未成年组。再对这两组乘客分别统计不同性别
# 的人的平均获救可能性
df['Deraged'] = df['Age'] > 18
df.pivot_table(index = 'Deraged', columns='Sex', values='Survived', aggfunc='mean')

groupby操作

df = pd.DataFrame({'key':['A','B','C','A','B','C','A','B','C'], 'data':[0,5,10,5,10,15,10,15,20]})

如果想统计各个key中对应的data数值总和是多少,就可以用到groupby

df.groupby('key').sum()

继续用泰坦尼克号数据集,下面计算按照不同性别统计其年龄的平均值

df = pd.read_csv('titanic.csv')
df.groupby('Sex')['Age'].mean()

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
               'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
               'C' : np.random.randn(8),
               'D' : np.random.randn(8)})

# 表示A在取不同key值时,B、C、D中样本的数量
grouped = df.groupby('A')
grouped.count()

也可以指定多个对象

grouped = df.groupby(['A', 'B'])
grouped.count()

指定好操作对象之后,通常还需要设置下计算或者统计的方法,比如求和:

grouped = df.groupby(['A', 'B'])
grouped.aggregate(np.sum)

此处的索引就是按照传入参数的顺序来指定的,如果大家习惯用数值编号索引也是可以的,只需要加入as_index参数:

grouped = df.groupby(['A', 'B'], as_index=False)
grouped.aggregate(np.sum)

groupby操作之后仍然可以使用describe()方法来展示所有统计信息

grouped.describe().head()

也可以自己设置需要的统计指标:

grouped = df.groupby('A')
grouped['C'].agg([np.sum, np.mean, np.std])    

在groupby操作中还可以指定操作的索引(也就是level):

arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
      ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
index = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])

下面按照索引进行groupby操作:

s = pd.Series(np.random.randn(8), index=index)

grouped = s.groupby(level = 0)
grouped.sum()

grouped = s.groupby(level=1)
grouped.sum()

通过level参数可以指定以哪项为索引进行计算,当level为0时,设置名为first的索引;当level为1时,设置名为second的索引。

grouped = s.groupby(level = 'first') 
grouped.sum()

三、常用函数操作

Merge操作

left = pd.DataFrame({'key' : ['K0', 'K1', 'K2', 'K3'],
                     'A' : ['A0', 'A1', 'A2', 'A3'],
                     'B' : ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key' : ['K0', 'K1', 'K2', 'K3'],
                      'C' : ['C0', 'C1', 'C2', 'C3'],
                      'D' : ['D0', 'D1', 'D2', 'D3']})

先创建两个DataFrame,然后用merge将两个DataFrame整合到一起

res = pd.merge(left, right, on = 'key')

这是按照key列把两份数据整合在一起,假如key列不同

left = pd.DataFrame({'key1' : ['K0', 'K1', 'K2', 'K3'],
                     'key2' : ['K0', 'K1', 'K2', 'K3'],
                     'A' : ['A0', 'A1', 'A2', 'A3'],
                     'B' : ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1' : ['K0', 'K1', 'K2', 'K3'],
                      'key2' : ['K0', 'K1', 'K2', 'K4'],
                      'C' : ['C0', 'C1', 'C2', 'C3'],
                      'D' : ['D0', 'D1', 'D2', 'D3']})
res = pd.merge(left, right, on=['key1', 'key2'])

此时如果按照key1和key2整合两份数据,会发现最后一行的数据被抛弃了,如果想考虑所有的结果,还需要额外设置一个how参数:

res = pd.merge(left, right, on=['key1', 'key2'], how='outer')

还可以加入详细的组合说明,指定indicator参数为True即可

res = pd.merge(left, right, on=['key1', 'key2'], how='outer', indicator=True)

也可以单独设置只考虑左边数据或者只考虑右边数据,即以谁为准:

res = pd.merge(left, right, how='left' )

res = pd.merge(left, right, how='right' )    

缺失值处理

拿到数据之后,经常会遇到数据不干净的现象,即里面可能存在缺失值或者重复片段,这就需要先对数据进行预处理操作。

data = pd.DataFrame({'k1' : ['one']*3+['two']*4,
                 'k2' : [3, 2, 1, 3, 3, 4, 4]})

此时数据中有几条完全相同的,可以使用drop_duplicates函数去掉多余的数据:

data.drop_duplicates()

也可以只考虑某一列的重复情况,其他全部舍弃:

data.drop_duplicates(subset='k1')

如果要往数据中添加新的列,可以直接指定新的列名或者使用assign函数:

df = pd.DataFrame({'data1' : np.random.randn(5), 'data2' : np.random.randn(5)})
df2 = df.assign(ration = df['data1']/df['data2'])

在数据处理中也经常会遇到缺失值,Pandas中一般用NaN来表示,拿到数据之后,通常都会先看一看缺失情况:

df = pd.DataFrame([range(3), [0, np.nan, 0], [0, 0, np.nan], range(3)])

在创建中加入了两个缺失值,可以直接通过isnull()函数判断所有缺失情况:

df.isnull().any(axis=1)

用fillna函数来填充,在实际处理中通常使用的是均值、中位数等指标。

df.fillna(5)

时间操作

在机器学习中,从始至终都是尽可能多的利用数据所提供的信息,当然时间特征也不例外。当拿到一份时间特征时,最好还是将其转换成标准格式,这样在提取特征时更方便一些:

# 创建一个时间戳
ts = pd.Timestamp('2017-11-24')

s = pd.Series(['2017-11-24 00:00:00', '2017-11-25 00:00:00', '2017-11-26 00:00:00'])
# 将Series转换为标准格式
ts = pd.to_datetime(s)

读取数据时,如果想以时间特征为索引,可以将parse_dates参数设置为True:

data = pd.read_csv('flowdata.csv', index_col=0, parse_dates=True)

有了索引后,就可以用它来取数据了:

data[pd.Timestamp('2012-01-01 09:00'):pd.Timestamp('2012-01-01 19:00')]
# 取2013年的数据
data['2013']

还有个重要的内容:resample重采样:

data.resample('D').mean().head()

原始数据中每天都有好几条数据,但是这里想统计的是每天的平均指标,当然也可以计算其最大值、最小值,只需要把.mean()换成.max()或者.min()即可。
例如想按3天为一个周期进行统计:

data.resample('3D').mean().head()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值