前言
大数据时代,数据的重要性不言而喻,掌握数据者得天下。很多同学可能对一堆数据不知如何进行处理分析得到有用的信息,本文主要基于anaconda 简单介绍 Numpy 模块的使用,重点演示 Pandas 的应用。
数据分析:把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律
数据分析三剑客:Numpy,Pandas,Matplotlib
Numpy与Padas是数据结构、Matplotlib绘图使用
环境准备
使用np.array()创建
数组
import numpy as np
np.array([1,2,3])
np.array([[1,2,3], [4,5,6]])
matplotlib绘图
import matplotlib.pylab as plt
np的数组(4)
linspace
np.linspace(start, stop, num)
arange:等差数列
np.arange([start,] stop[, step,], dtype=None)
np.arange(0, 10, 2)
random.randint():随机数
np.random.randint(randint(low, high=None, size=None, dtype=‘l‘)
np.random.seed(10)
np.random.randint(0,100, size=(4,5))
random.random(size)
操作(4)
索引
arr[1] # 第一个元素,索引从 0 开始
arr[2, 3] # 第二行第三列元素
切片
arr[0:2] # 前两行
arr[:, 0:2] # , 左边是行,右边是列
arr[::-1] # 行倒序
arr[:, ::-1] # 列倒序
arr[:, ::-1, :]
变形:参数是一个tuple
arr.reshape()
arr.reshape((20,))
arr.reshape((1, 20))
arr.reshape(1, 20)
arr.reshape((-1, 4))
级联
数据的拼接,注意行或列的长度
ndarray排序
sort排序
np.sort(arr, axis=-1, kind=‘quicksort‘, order=None)
arr.sort(axis=0)
np.sort(arr, axis=0)
Note(2)
axis=0:表示针对行进行计算或排序,列有序
axis=1:表示针对列进行计算或排序,行有序
loc # 基于列label,可选取特定行(根据行index)
iloc # 基于行/列的position(默认的索引,整型)
at # 根据指定行index及列label,快速定位DataFrame的元素
iat # 与at类似,不同的是根据position来定位的
ix # 为loc与iloc的混合体,既支持label也支持position
导入需要的包
import pandas as pd
from pandas import Series, DataFrame
import numpy as np
创建和去重
是一种类似与一维数组的对象
values:一组数据(ndarray类型)
index:相关的数据索引标签
创建:由列表或numpy数组创建
默认索引为0到N-1的整数型索引
一定是一维的数据结构
隐式索引和显示索引可以共存
Series(data=[1,2,3]) # 隐式索引
Series(data=[1,2,3], index=[a,b,c]) # 显示索引,提高可读性
Series(data=np.random.randint(0,100, size=(4)))
s = Series(data=[1,1,1,2,3,4,5,5,6])
s.unique()
运算:只能针对索引对齐的数据运算,否则为NaN
Series基本概念
可以通过shape,size,index,values等得到series的属性
s.index # 索引
s.values # 值
s.size # 长度
s.shape # (n,)
可以使用s.head(),tail()分别查看前n个和后n个值,head默认为 5
s.head(2)
s.tail(2)
去重
s.unique()
Series的运算:索引一致则相加,不一致则为Na
s1.add(s2,fill_value=0)
s1.mul(s2,fill_value=1)
Note(2)
默认格式:dtype: int64
Series之间的运算,自动对齐不同索引的数据,如果索引不对应,则补NaN
创建DataFrame
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引。
使用字典创建的DataFrame后,则columns参数将不可被使用。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
df = DataFrame(data=np.random.randint(0,100, size=(3,3)), index=(‘a‘, ‘b‘, ‘c‘), columns=(‘1‘, ‘2‘, ‘3‘))
dic = {
‘张三‘:[11,22,33,44],
‘李四‘:[55,66,77,88]
}
df_score = DataFrame(data=dic,index=[‘语文‘,‘数学‘,‘英语‘,‘理综‘])
df.shape / .index /.colums /.vlues
切片
【注意】 直接用中括号时
索引表示的是列索引
切片表示的是行切片
df[‘a‘:‘b‘]
df[0:2]
df.loc[:, ‘A‘:‘B‘]
df.iloc[:, 0:2]
股票示例
df.to_save(‘xxx.csv‘)
pd.read_csv(‘xxx.csv‘, index_col=‘date‘, parse_dates=True):把字符串日期转为 Timestamp
df.drop(labels=[‘列名‘], axis=1 ,inplace=True):删除某一列
df[‘close‘].shift(1):向下移动一个单元,对齐其他列的下一行
new_df.resample(‘M‘).first():获取每个月的第一条
new_df.resample(‘A‘).last():获取每年的最后一条
import tushare as ts
import pands as pd
df = ts.get_k_data(code=‘600519‘,start=‘2000-01-01‘)
df.to_csv(‘./maotai.csv‘)
df = pd.read_csv(‘./maotai.csv‘)
df.drop(labels=[‘Unnamed: 0‘], axis=1, inplace=True)
df = pd.read_csv(‘./maotai.csv‘,index_col=‘date‘,parse_dates=[‘date‘])
df.index[0]
df.columns[0]
输出该股票所有收盘比开盘上涨3%以上的日期。
df[(df.open - df.close)/df.open > 0.03]
df.loc[(df[‘close‘] - df[‘open‘]) / df[‘open‘] > 0.03].index
输出该股票所有开盘比前日收盘跌幅超过2%的日期。
df[(df.open - df.close.shift(1)) / df.close.shift(1) < -0.02].index
假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?
new_df = df[‘2010-01-01‘:‘2019-09-03‘]
df_monthly = new_df.resample(‘M‘).first()
df_yearly = new_df.resample(‘A‘).last()[:-1]
cost = df_monthly[‘open‘].sum() * 100
recv = df_yearly[‘open‘].sum() * 1200
recv = 900 * new_df[-1:][‘open‘] + recv
recv - cost
pandas的数据处理
处理丢失的数据
numpy:没有异常值清洗
pandas处理空值(3)
isnull()
notnull()
dropna():过滤丢失的数据
fillna():填充丢失的数据
df.isnull()
df.notnull()
df.notnull().any(axis=1) # any表示or
df.notnull().all(axis=1) # and
df.loc[df.notnull().all(axis=1)] or
indexs = df.loc[df.isnull().any(axis=1)].index
df.drop[labels=indexs, axis=0]
df.loc[df.isnull().any(axis=1)]
df.dropna(axis=0):删除空行
df.fillna(axis=0):用列的值进行替换
df.dropna(axis=0)
df.fillna(value=‘目标值‘, method=‘ffill‘, axis=0)
读取excel
df = pd.read_excel(‘文件路径.xlsx‘, sheet_name=‘xxx‘)
df = df.drop(labels=[‘none‘, ‘none1‘], axis=1 inplace=True)
df.dropna(axis=0)
df.loc[df.notnull().all(axis=1)]
df=df.fillna(method=‘ffill‘, axis=0).fillna(method=‘bfill‘, axis=0)
df.notnull().all(axis=0)
df.isnull().any(axis=0)
pd.concat()级联
axis=0/1
join=‘outer‘/‘inner‘
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致。有2种连接方式:
外连接:补NaN(默认模式)
内连接:只连接匹配的项
df1 = DataFrame(np.random.randint(1,100, size=(5,5)))
df2 = DataFrame(np.random.randint(1,100, size=(5,5)))
pd.concat((df1, df1), axis=0, join=‘outer‘)
pd.merge()合并
一次只能用于两张表,用于数据的整合
参数说明
left, right,
how=‘inner/outer/left/right‘
on=‘列名‘ , left_on=‘‘, right_on=‘‘
merge与concat的区别在于,merge需要依据某一共同的列来进行合并,使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意每一列元素的顺序不要求一致
数据准备
dic1 = {
‘name‘:[‘henry‘,‘echo‘, ‘dean‘, ‘tom‘],
‘apartment‘:[‘tech‘,‘sale‘,‘hr‘, ‘xx‘],
}
df1 = DataFrame(dic1, index=[‘a‘, ‘b‘, ‘c‘])
一对一
人口分析案例
找出2010年的全民人口数据
10.计算各州的人口密度 排序,并找出人口密度最高的五个州 df.sort_values()
how=‘outer‘:要保留所有数据
数据分析中要保证数据的完整性
import pandas as pd
import numpy as np
from pandas import Series, DataFrame
peo = pd.read_csv(‘./data/state-population.csv‘)
area = pd.read_csv(‘./data/state-areas.csv‘)
abbr = pd.read_csv(‘./data/state-abbrevs.csv‘)
abbr_peo = pd.merge(abbr, peo, left_on=‘abbreviation‘, right_on=‘state/region‘, how=‘outer‘)
abbr_peo.drop(labels=‘abbreviation‘, axis=1,inplace=True)
abbr_peo.head(2)
abbr_peo.isnull().any(axis=0)
abbr_peo.loc[abbr_peo.state[abbr_peo.state.isnull()].index][‘state/region‘].unique()
indexs = abbr_peo[abbr_peo[‘state/region‘] == ‘PR‘].index
abbr_peo.loc[indexs, ‘state‘] = ‘PUERTO RICO‘
indexs = abbr_peo[abbr_peo[‘state/region‘] == ‘USA‘].index
abbr_peo.loc[indexs, ‘state‘] = ‘UNITED STATES‘
abbr_peo_area = pd.merge(abbr_peo, area, how=‘outer‘)
abbr_peo_area.head(2)
indexs = abbr_peo_area[abbr_peo_area[‘area (sq. mi)‘].isnull()].index
abbr_peo_area.drop(labels=indexs, axis=0, inplace=True)
abbr_peo_area.query("ages==‘total‘and year==2010")
abbr_peo_area.peo_dense = abbr_peo_area.population / abbr_peo_area[‘area (sq. mi)‘]
abbr_peo_area.head(2)
abbr_peo_area.sort_values(by=‘peo_dense‘,axis=0, ascending=False).head(2)
drop_duplicates:删重
df.drop_duplicates(keep=‘first/last‘/False)
keep参数:指定保留哪一重复的行数据
df[0:2] = 6
df.iloc[5] = 6
replace(to_replace=[]/{}, value=‘xxx‘):替换
使用replace()函数,对values进行映射操作
单值替换
普通替换: 替换所有符合要求的元素:to_replace=15,value=‘e‘
按列指定单值替换: to_replace={列标签:替换值} value=‘value‘
多值替换
列表替换: to_replace=[] value=[]
字典替换(推荐) to_replace={to_replace:value,to_replace:value}
df.replace(to_replace={64:‘xxx‘})
map():映射
映射关系表:dict={}
map()函数:新建一列,map函数并不是df的方法,而是series的方法
map()可以映射新一列数据
map()中可以使用lambd表达式
map()中可以使用方法,可以是自定义的方法
注意 :map()中不能使用sum之类的函数,for循环
dic = {
‘name‘:[‘周杰伦‘,‘张三‘,‘周杰伦‘],
‘salary‘:[15000,20000,15000]
}
df = DataFrame(data=dic)
df
name salary
0 周杰伦 15000
1 张三 20000
2 周杰伦 15000
dic = {
‘周杰伦‘:‘jay‘,
‘张三‘:‘tom‘
}
df[‘ename‘] = df.name.map(dic)
name salary ename
0 周杰伦 15000 jay
1 张三 20000 tom
2 周杰伦 15000 jay
df.ename = df.name.map(dic)
df[‘neat_salary‘] = df.salary.map(lambda x: x - (x-3000)*0.5)
df
使用聚合操作对异常值检测和过滤
使用df.std()函数可以求得DataFrame对象的标准差
创建一个1000行3列的df 范围(0-1),求其每一列的标准差
df = DataFrame(np.random.random(size=(1000, 3)), columns=[‘A‘, ‘B‘, ‘C‘])
df.C.std()
indexs = df[df.C > 3*df.C.std()].index
indexs
分组
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理
分组:先把数据分为几组
用函数处理:为不同组的数据应用不同的函数以转换数据
合并:把不同组得到的结果合并起来
数据分类处理的核心
groupby()函数
groups属性查看分组情况
eg: df.groupby(by=‘item‘).groups
数据准备
df = DataFrame({‘item‘:[‘Apple‘,‘Banana‘,‘Orange‘,‘Banana‘,‘Orange‘,‘Apple‘],
‘price‘:[4,3,3,2.5,4,2],
‘color‘:[‘red‘,‘yellow‘,‘yellow‘,‘green‘,‘green‘,‘green‘],
‘weight‘:[12,20,50,30,20,44]})
df
item price color weight
0 Apple 4.0 red 12
1 Banana 3.0 yellow 20
2 Orange 3.0 yellow 50
3 Banana 2.5 green 30
4 Orange 4.0 green 20
5 Apple 2.0 green 44
groupby(‘分组条件‘)
df.groupby(by=‘item‘, axis=0)
df.groupby(by=‘item‘, axis=0).groups
{‘Apple‘: Int64Index([0, 5], dtype=‘int64‘),
‘Banana‘: Int64Index([1, 3], dtype=‘int64‘),
‘Orange‘: Int64Index([2, 4], dtype=‘int64‘)}
聚合
mean_price = df.groupby(by=‘item‘, axis=0).price.mean()
df[‘mean_price‘] = df.item.map(mean_price)
df
color_price = df.groupby(by=‘color‘, axis=0).price.mean()
df[‘color_price‘] = df.color.map(color_price)
df
aplly_my_mean = df.groupby(by=‘item‘, axis=0).price.apply(my_mean)
df[‘apply_my_mean‘] = df.item.map(aplly_my_mean)
df
transform_my_mean = df.groupby(by=‘item‘, axis=0).price.transform(my_mean)
df[‘transform_my_mean‘] = transform_my_mean
df
美国12政治选举案例
需求
cand_nm(候选人姓名),contbr_nm(捐赠者姓名), contbr_city,contbr_st, contbr_zip, contbr_employer, contbr_occupation(捐赠者的职业), contb_receipt_amt(捐赠金额), contb_receipt_dt(捐赠日期)
得到每天各政党所收政治献金数目。 考察知识点:groupby(多个字段)
10.查看老兵(捐献者职业)DISABLED VETERAN主要支持谁 :查看老兵们捐赠给谁的钱最多
11.找出各个候选人的捐赠者中,捐赠金额最大的人的职业以及捐献额 .通过query("查询条件来查找捐献人职业")
df[‘party‘].value_counts()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
usa_election = pd.read_csv(‘./data/usa_election.txt‘)
usa_election.head(2)
usa_election[‘parties‘] = usa_election[‘cand_nm‘].map(parties)
usa_election.head(2)
usa_election.parties.unique()
usa_election.parties.value_counts()
usa_election.groupby(by=‘parties‘).contb_receipt_amt.sum()
usa_election.groupby(by=[‘contb_receipt_dt‘, ‘parties‘])[‘contb_receipt_amt‘].sum()
date = usa_election.contb_receipt_dt
def transformDate(data):
for i in range(len(date)):
new_date = {}
day, month, year = date[i].split(‘-‘)
month = months[month]
return ‘-‘.join([‘20‘+year, str(month), day])
usa_election[‘contb_receipt_dt‘] = usa_election.contb_receipt_dt.map(transformDate)
usa_election.head(2)
usa_election.groupby(by=[‘contb_receipt_dt‘, ‘parties‘]).contb_receipt_amt.sum()
df = usa_election[usa_election.contbr_occupation ==‘DISABLED VETERAN‘]
df.groupby(by=‘cand_nm‘).contb_receipt_amt.sum()
max_amt = usa_election.groupby(by=[‘cand_nm‘])[‘contb_receipt_amt‘].max()
max_amt
for i in range(max_amt.size):
max_money = max_amt[i]
# for 循环中不显示执行结果,需要使用display或者print
display(usa_election.query(‘contb_receipt_amt == ‘+str(max_money))
原文:https://www.cnblogs.com/yx12138/p/11585798.html