python技巧
seaborn美化图片之设置背景
import seaborn as sns
sns.set_style('white')
plt.scatter(X_2[:,0],X_2[:,1],c=Y_train,cmap=plt.cm.prism)
设置背景后画面特别干净利落,不举例子了。
这个其实主要美化统计图的
例如:
score由
[array([ 1. , 0.90909091, 1. , 0.72727273, 0.9 ,
1. , 1. , 1. , 1. , 0.88888889]),
array([ 0.91666667, 0.90909091, 0.90909091, 0.72727273, 1. ,
1. , 1. , 1. , 1. , 0.88888889]),
等等这种数据组成,并且
np.array(score).shape=(20L, 10L)
score_means=np.mean(score,axis=1)
k_grid=np.arange(20)+1
普通的作图:
plt.boxplot(score)
plt.scatter(k_grid,score_means)
plt.ylim(0.8, 1.1)
plt.title('Accuracy as a function of $k$')
plt.ylabel('Accuracy')
plt.xlabel('Choice of k')
plt.show()
美化之后
sns.boxplot(score)
plt.scatter(k_grid,score_means)
plt.ylim(0.8, 1.1)
plt.title('Accuracy as a function of $k$')
plt.ylabel('Accuracy')
plt.xlabel('Choice of k')
plt.show()
如何读取网络zip文件的链接
import StringIO
import requests
import zipfile
def getZip(url):
r=requests.get(url).content
s=StringIO.StringIO(r)
rs=zipfile.ZipFile(s)
return rs
r=requests.get(url).content
从网页链接中读取内容,但这个内容是压缩文件,我们不便于操作,因此要用zipfile解压,而zipfile.ZipFile的输入参数必须是a file (a string) or a file-like object因此需可以通过stringIO.StringIO(r)网将页输出转化为string buffer 然后再传给zipfile.ZipFile进行解压
接下来,可以这么操作:
print rz.namelist()
['SchoolsPlayers.csv', 'SeriesPost.csv', 'Teams.csv', 'TeamsFranchises.csv', 'TeamsHalf.csv', 'AllstarFull.csv', 'Appearances.csv', 'AwardsManagers.csv', 'AwardsPlayers.csv', 'AwardsShareManagers.csv', 'AwardsSharePlayers.csv', 'Batting.csv', 'BattingPost.csv', 'Fielding.csv', 'FieldingOF.csv', 'FieldingPost.csv', 'HallOfFame.csv', 'Managers.csv', 'ManagersHalf.csv', 'Master.csv', 'Pitching.csv', 'PitchingPost.csv', 'readme2013.txt', 'Salaries.csv', 'Schools.csv']
salary=rz.open('Salaries.csv')
DataFrame相关
有用的命令
- df.dtypes 返回各个column的数据类型
- df.info() 比上一个的更多信息
- df.describe() 你懂的
- type(df['Age'])
类型转换
df['AgeIsNull'] = pd.isnull(df.Age).astype(int)
分析df的时候,一般不要操作原始的数据列,而是自己创建新的列,由于我们最终一般要把数据传给sklearn处理,而它不处理字符串,因此数据处理的目标也就是将字串信息转化成数字,存到新的列里边,示例:
df.dtypes[df.dtypes.map(lambda x: x=='object')]
Name object
Sex object
Ticket object
Cabin object
Embarked object
dtype: object
这些如果有用转换到新的列,如果没用就不用管了,最后都删掉
df = df.drop(['Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1)
然后再转化成array
train_data = df.values
注:df.dtypes
PassengerId int64
Survived int64
Pclass int64
Name object
Sex object
object类型的一般都是含有字符串的
map还可以这么用!
df['Gender'] = df['Sex'].map( {'female': 0, 'male': 1} ).astype(int)
读入时,将第一列作为index
- 直接
exprs=pd.read_csv(exprsUrl,index_col=0)
- 笨一点的方法;
exprs=pd.read_csv(exprsUrl) exprs.index=exprs.loc[:,exprs.columns[0]] exprs=exprs.drop(exprs.columns[0],axis=1)
日期提取
sampleinfo["date"]=pd.to_datetime(sampleinfo.date)
sampleinfo["year"]=map(lambda x:x.year,sampleinfo['date'])
sampleinfo["month"]=map(lambda x:x.month,sampleinfo['date'])
注意等号左边的必须是双引号,我还没搞懂为啥
日期运算:计算逝去的days
dateOrigin=dt.datetime(2002,10,31)
sampleinfo["elapsedInDays"]=map(lambda x:(x-dateOrigin).days,sampleinfo.date)
每一行的数据分别减去所在行的均值:
data = exprsCEU.apply(lambda x: x - exprsCEU.mean(axis=1), axis = 0)
data.head()
分组和变换
df=pd.read_csv(salary)
df.head()
yearID teamID lgID playerID salary
0 1985 BAL AL murraed02 1472819
1 1985 BAL AL lynnfr01 1090000
2 1985 BAL AL ripkeca01 800000
3 1985 BAL AL lacyle01 725000
4 1985 BAL AL flanami01 641667
如何得到每年每个team的总的salary呢?
- 方法1:使用聚合函数agg
dfSalary=df.groupby(['yearID','teamID'],as_index=False)['salary'].agg({'total salary':sum})
dfSalary.head()
yearID teamID total salary
0 1985 ATL 14807000
1 1985 BAL 11560712
2 1985 BOS 10897560
3 1985 CAL 14427894
4 1985 CHA 9846178
注意聚合函数里面如果是字典的话,我们就可以自己指定聚合后的列的名称,如果不用字典,那就是
dfSalary=df.groupby(['yearID','teamID'],as_index=False)['salary'].agg(sum)
结果的column和原来一样
注意传递到sum的参数是每一个组的salary,因此这个sum就是每一个group的salary之和
强调一遍group函数的返回值是grouped类型
dfSalary=df.groupby(['yearID','teamID'],as_index=False)['salary'].agg({'total salary':sum})
实际上是两步:
grouped=df.groupby(['yearID','teamID'],as_index=False) dfSalary=grouped['salary'].agg({'total salary':sum})
聚合的时候传递给聚合函数的是每一组的数据!
- 方法2:使用apply
dfSalary=df.groupby(['yearID','teamID'],as_index=False)['salary'].apply(lambda x:pd.Series({'totalSumary':sum(x)})) dfSalary.head()
结果是multi Index的,这是一种可以表示多维数据的方法,但是multi index表示以后不方便和其他dataframe 融合了,可以通过
dfSalary.reset_index()将index复原
另:apply(lambda x:pd.Series({'totalSumary':sum(x)}))
这个地方必须得是Series因为Series可以每个组进行连接,而dataframe不行
merge两个DataFrame
和
dfTeam=dfTeam[['yearID','teamID','W']] dfTeam.head()
yearID teamID W
0 1871 PH1 21
1 1871 CH1 19
2 1871 BS1 20
3 1871 WS3 15
4 1871 NY2 16
使用
dfMerge=pd.merge(dfSalary,dfTeam,how='inner',on=['yearID','teamID']) dfMerge.head()
得
index yearID teamID totalSumary W
0 0 1985 ATL 14807000 66
1 1 1985 BAL 11560712 83
2 2 1985 BOS 10897560 81
3 3 1985 CAL 14427894 90
4 4 1985 CHA 9846178 85
merge函数的how='inner'表示连接的方式,on表明要按照哪几列进行连接,'inner'表示结果只取两者的同样的列值的交的部分,而‘outer'表示按照两者列的并进行的,没有的地方是na
如何数元素的数目 collections.Counter([iterable-or-mapping])
摘自链接
states=['KY', 'AR', 'MI', 'LA', 'NH', 'WV', 'NH', 'NC', 'VA', 'CO', 'IL', 'AK', 'IA', 'MS', 'OR', 'GA', 'NE', 'SD', 'ME', 'MN', 'TX', 'SC', 'SC', 'OK', 'NM', 'NJ', 'ID', 'TN', 'WY', 'KS', 'HI', 'OK', 'MT', 'RI', 'MA', 'DE']
import collections
counter=collections.Counter(states)
- 返回值可以看作字典
- counter['KY']返回1
- counter['SC']返回2
- 只是增加了一项功能:查询不在对象中的元素时返回0
- counter['haha']返回0
- 查看出现多次的元素
twopollindex = [key for key in counter.keys() if counter[key]>1]
结果['NH', 'OK', 'SC']
比较两个array是否接近
np.allclose(a, b)