【Python实战】Pandas:让你像写SQL一样做数据分析(二)
2016-07-19 20:10
856 查看
1. 引言
前一篇介绍了Pandas实现简单的SQL操作,本篇中将主要介绍一些相对复杂一点的操作。为了方便后面实操,先给出一份简化版的设备统计数据:0 android NLL 387546520 2099457911 0 ios NLL 52877990 916421755 1 android 魅族 8995958 120369597 1 android 酷派 9915906 200818172 1 android 三星 16500493 718969514 1 android 小米 23933856 290787590 1 android 华为 26706736 641907761 1 ios 苹果 52877990 916421755 2 android 小米-小米4 2786675 55376581 2 android 魅族-m2-note 4642112 130984205 2 android OPPO-A31 4893428 62976997 2 ios 苹果-iPhone-6s 5728609 99948716
其中,第一列表示维度组合编号,第二列表示操作系统类型,第三列为维度值(NLL表示缺失,即第一行、第二行表示操作系统的统计,其余表示厂商或机型),第三列、第四列分别表示UV、PV;且字段之间为
\t分隔。读取该文件为DataFrame:
import pandas as pd df = pd.read_csv(path, names=['id', 'os', 'dim', 'uv', 'pv'], sep='\t')
2. 实战
Add
在原dataframe上,增加一行数据;可通过dataframe的append函数来追加:import numpy as np row_df = pd.DataFrame(np.array([['2', 'ios', '苹果-iPad 4', 3287509, 32891811]]), columns=['id', 'os', 'dim', 'uv', 'pv']) df = df.append(row_df, ignore_index=True)
增加一列数据,则比较简单:
df['time'] = '2016-07-19'
To Dict
关于android、ios的PV、UV的dict:def where(df, column_name, id_value): df = df[df[column_name] == id_value] return df def to_dict(df): """ {"pv" or "uv" -> {"os": os_value}} :return: dict """ df = where(df, 'id', 0) df_dict = df.set_index('os')[['uv', 'pv']].to_dict() return df_dict
Top
group某列后的top值,比如,android、ios的UV top 2的厂商:def group_top(df, group_col, sort_col, top_n): """ get top(`sort_col`) after group by `group_col` :param df: dataframe :param group_col: string, column name :param sort_col: string, column name :param top_n: int :return: dataframe """ return df.assign(rn=df.sort_values([sort_col], ascending=False) .groupby(group_col) .cumcount() + 1) \ .query('rn < ' + str(top_n + 1)) \ .sort_values([group_col, 'rn'])
全局top值加上group某列后的top值,并有去重:
def top(df, group_col, sort_col, top_n): """overall top and group top""" all_top_df = df.nlargest(top_n, columns=sort_col) grouped_top_df = group_top(df, group_col, sort_col, top_n) grouped_top_df = grouped_top_df.ix[:, 0:-1] result_df = pd.concat([all_top_df, grouped_top_df]).drop_duplicates() return result_df
排序编号
对某列排序后并编号,相当于给出排序名次。比如,对UV的排序编号:df['rank'] = df['uv'].rank(method='first', ascending=False).apply(lambda x: int(x))
Left Join
Pandas的left join对NULL的列没有指定默认值,下面给出简单的实现:def left_join(left, right, on, right_col, default_value): df = pd.merge(left, right, how='left', on=on) df[right_col] = df[right_col].map(lambda x: default_value if pd.isnull(x) else x) return df
自定义
对某一列做较为复杂的自定义操作,比如,厂商的UV占比:def percentage(part, whole): return round(100*float(part)/float(whole), 2) os_dict = to_dict(df) all_uv = sum(os_dict['uv'].values()) df = where(df, 'id', 1) df['per'] = df.apply(lambda r: percentage(r['uv'], all_uv), axis=1)
重复值
某列的重复值的行:duplicate = df.duplicated(subset=columns, keep=False)
写MySQL
Pandas的to_sql函数支持Dataframe直接写MySQL数据库。在公司开发时,常常会有办公网与研发网是不通的,Python的sshtunnel模块提供ssh通道,便于入库debug。import MySQLdb from sshtunnel import SSHTunnelForwarder with SSHTunnelForwarder(('porxy host', port), ssh_password='os passwd', ssh_username='os user name', remote_bind_address=('mysql host', 3306)) as server: conn = MySQLdb.connect(host="127.0.0.1", user="mysql user name", passwd="mysql passwd", db="db name", port=server.local_bind_port, charset='utf8') df.to_sql(name='tb name', con=conn, flavor='mysql', if_exists='append', index=False)
相关文章推荐
- python核心编程学习笔记-2016-07-19-02-__name__
- python 遍历目录
- Python学习进程(6)函数
- python3的列表、元组、集合、字典操作
- 【python】import 模块、包、第三方模块
- python练习——最长的递减子序列
- python核心编程学习笔记-2016-07-19-01-sys.exit()
- leetcode-python 第四周
- python3的函数调用
- Python——5函数
- python3的迭代器和生成器
- caffe的python接口学习(6):用训练好的模型(caffemodel)来分类新的图片
- python3的循环和条件控制
- python多线程(1)--单线程和多线程
- EM算法与高斯混合聚类
- python3的运算符
- caffe的python接口学习(5):生成deploy文件
- Python高阶函数:filter、map、reduce、lambda
- Python查询数据库时间类型列
- python -- 计算数学题--用程序解决问题1