最近一直在忙着处理数据,以下是我作为python和数据分析的入门小白,在最近几周的工作中总结的一些经验。
Pandas
高性能、简单易用的数据结构和数据分析工具
DataFrame/Series常用
DataFrame
构建DataFrame
查看头部df.head()
查看尾部(n个元素)df.tail(n)
以Day字段为索引df = df.set_index('Day')
选择某一列 df['Visitors']
或 df.Visitors
如果有空格,使用第一种
将df一列转为list(列行转)df.Visitors.tolist()
多列转数组np.array(df[['Bounce_Rate','Visitors']])
重命名列名
数据的快速统计汇总df.describe()
查看更多的百分位数df.describe(percentiles=[.20,.40,.80,.90,.95])
筛选:
删除多列:df.drop(['col1', 'col2'], axis=1) # inplace=True指定替换原df
删除多记录:df.drop([22,33], axis=0)
分组聚合查询:
选择Pclass和Survived列,按照Pclass聚合,按平均值降序排列查看:
train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)
分组count:df1.groupby('p.trade_status')['p.trade_status'].value_counts()
处理缺失数据:df = df.dropna(axis=1, thresh=100) # 删除非NaN值小于100的列
map: 转变数据框(df)中的某个列的列数据
将class列的数据替换为更简单的名称,并将原列替换df['class'] = df['class'].map({'Iris-setosa': 'SET', 'Iris-virginica': 'VIR', 'Iris-versicolor': 'VER'})
apply :
既可以在DataFrame上工作,也可在Series上工作。df['wide petal'] = df['petal width'].apply(lambda v: 1 if v >= 1.3 else 0)
axis :
- 0 or ‘index’: apply function to each column
- 1 or ‘columns’: apply function to each row
按行处理整个dfdf['petal area'] = df.apply(lambda r: r['petal length'] * r['petal width'], axis=1)
按行更新,如果是nan就更新成另一个行
|
|
在apply的函数中,获取行号:使用row.name属性
applymap :对整个df所有数据单元执行一个函数df.applymap(lambda v: np.log(v) if isinstance(v, float) else v)
数据切片 ilocdf.iloc[:3, :2]
tip: ix vs iloc vs loc
- loc 通过行标签索引行数据(works on labels in the index.),如loc[1]表示索引的是第一行,loc[‘d’]表示索引的是’d’行,loc[:, [‘c’]] 索引’c’列
- iloc 通过行号获取行数据(works on the positions in the index (so it only takes integers)) ,
- ix usually tries to behave like loc but falls back to behaving like iloc if the label is not in the index. pandas 0.20.0 及以上废除
重置索引(如截取了一个子df,索引保持原样,可以重置索引从0开始)df.reset_index(drop=True)
检查数据相关性:df.corr()
通过传递method参数,还可以切换到Kendall’s tau或Spearman’sdf.corr(method='spearman')
df.corr(method='kendall')
Series
unique() 相当与sql distinctdf['class'].unique()
round : 四舍五入df.round(n) # 保留n位小数
或df['col'].round(n)
找重复数据:df.duplicated()
pivot_table 以电子表格形式显示数据names.pivot_table('births',columns='sex',aggfunc=sum,index='year') # 统计对象为births列,纵坐标以sex列划分,横坐标为year,使用sum函数聚合
字符串替换:f['date'] = f['date'].str.replace('日','')
聚合Group by :
使用group by - apply 分组并加入列
分组取top 1000:top1000 = names.groupby(['year','sex']).apply(lambda g : g.sort_values(by='births', ascending=False)[:1000])
样本值的累积和:df.cumsum()
找到已排序的series中n应该插入的位置:series.searchsorted(n)
处理时间:login_df['createtime'] = pd.to_datetime(login_df[['year','month','day','hour','minute','second']]) # login_df包含了年月日时分秒的列
I/O Basics
从csv文件读取到df:df = pd.read_csv('filename')
从df写入到csv:df.to_csv('newcsv.csv')
读取页面的tables为dataFrame list:dfs = df.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
处理utf8编码的嵌套json数据(规则化json数据):
读取mysql数据到df(pandas处理sql要借助SQLAlchemy,一个类似java中mybatis的orm工具,具体实现还要依赖各种数据库连接驱动模块):
读取oracle大批数据到df:
df数据写入到oracle
数据合并:
join: 主要用于索引上的合并df.join(self, other, on=None, how='left', lsuffix='', rsuffix='',sort=False)
merge: 默认以重叠的列名当做连接键,默认inner连接pd.merge(df1,df2,on='Year',how='outer')
how 类似mysql join方式,有left, right, inner, outer ,连接键名称不同,可使用left_on和right_on指定;以索引当做连接键:left_index=true,right_index=True
on可以指定多个col,on=['Year','Month']
concat: 相当于DB中的全连接(union all) concat方法相当于数据库中的全连接(UNION ALL),可以指定按某个轴进行连接,也可以指定连接的方式join(outer,inner 只有这两种)。与数据库不同的时concat不会去重,要达到去重的效果可以使用drop_duplicates方法pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False)
常用:pd.concat(some_list, ignore_index=True)
持久化
python原生pickle
pandas pickle
其他
pd.get_dummies 属性平展
pandas中判断NaN类型:
需要筛选后处理数据时,使用copy,否则一些操作会返回一个view,这样在更新时就会有问题
多level降低:(尤其适用于在excel读入的多表头数据)frame.columns = frame.columns.droplevel()
bool 数组取反使用”-“pool[ -(pool.USERID.str.contains('\|'))]
df中index不是column!
NumPy
np.allclose : 检查是否近似np.allclose(names.groupby(['year','sex']).prop.sum(),1)
四舍五入np.round(3.45, 0)
取随机整数np.random.randint(50) # 0~49
np.array配合查找df
创建ndarray:arr1 = np.arra([...])
查看数组维度arr1.ndim
数组形状:arr1.shape
数据结构arr1.dtype
使用zeros或ones创建长度或形状全0或全1的数组np.zeros(10)或np.zeros((3,6))
使用empty创建一个没有任何具体值的数组(并非返回全0数组,很多情况下返回未初始化的垃圾值)
python内置range的数组版本:np.arange(10)
创建一个正方的N*N单位矩阵(对角线为1,其余为0)np.eye(n)
dtype是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息np.array([1,2,3], dtype=np.float64)
np.array([1,2,3], dtype=np.int32)
numpy数据类型:
int8, uint8
int16, uint16
int32, uint32
int64, uint64
float16
float32 标准的单精度浮点数。与c的float兼容
float64 标准的双精度浮点数。与c的double和python的float对象兼容
float128
complex64, complex128, complex256 复数
bool
object Python对象类型
string 固定长度的字符串类型(每个字符1个字节)
unicode 固定长度的unicode类型(字节数由平台决定)
使用astype转换dtype(总会创建一个新数组)
arr.astype(np.float64)
不同大小的数组之间的运算叫做广播。
基本的索引和切片:arr[5]
arr[5:8]
arr[5:8] = 12
注意numpy数组跟python列表最大的不同是:数组切片是原始数组的视图,也就是数据并不会被复制。
如果需要复制,需要显式调用copy:arr[5:8].copy()
只有冒号表示选取整个轴:arr[:]
数组的比较运算也是矢量化的,names == ‘Bob’将返回一个布尔型数组
“非”可以用!=或负号-
应用多个布尔条件,使用&、|
通过布尔型索引选取数组中的数据,将总是创建数据的副本。
按比例生成随机数据:
|
|
三、Matplotlib 可视化
使用绘图主要是用于特征工程,发现暂时未知的因素对最终结果的影响
中文乱码的解决:
Python绘图鼻祖,
导入:
直方图:
散点图:
简单线图:
条形图:
小提琴图:
IPython
内省:
任何变量后输入?
,可以展示此对象的通用信息
变量或方法后输入??
,可以展示源码
配合*
可以实现查找IPython命名空间,如np.*load*?
使用%run f.py
运行f.py脚本
通过Ctrl - C
中断正在执行的代码
魔术命令:%timeit
在任何语句前,检测执行时间
使用?
查看魔术命令选项,如%reset?
%quickref
或%magic
,获取魔术命令文档
最近的两个输出结果分别保存在_
和__
中
使用%cd
、%pwd
执行常见操作
使用!
执行shell命令
使用 %bookmark
目录书签
表格打印
以下内容留待以后补充
四、Seaborn
使用pairplot查看不同特征维度pair下数据的空间分布状况(散点图和直方图):
五、Scikit-learn
sklearn.metrics.accuracy_score(y_true, y_pred)
六、statsmodels
用于探索数据、估计模型,并运行统计校验。