关于pandas:Python数据分析库介绍及引入惯例

文章和代码等曾经归档至【Github仓库:https://github.com/timerring/dive-into-AI】或者公众号【AIShareLab】回复 python数据分析 也可获取。python的毛病Python有一个叫做全局解释器锁(Global Interpreter Lock,GIL)的组件,这是一种避免解释器同时执行多条Python字节码指令的机制。这并不是说Python不能执行真正的多线程并行代码。例如,Python的C插件应用原生的C或C++的多线程,能够并行运行而不被GIL影响,只有它们不频繁地与Python对象交互。重要的python库NumPyNumPy(Numerical Python的简称)是Python科学计算的根底包。 疾速高效的多维数组对象ndarray。作为在算法和库之间传递数据的容器。对于数值型数据,NumPy数组在存储和解决数据时要比内置的Python数据结构高效得多。此外,由低级语言(比方C和Fortran)编写的库能够间接操作NumPy数组中的数据,无需进行任何数据复制工作。因而,许多Python的数值计算工具应用NumPy数组作为次要的数据结构。 pandaspandas提供了疾速便捷解决结构化数据的大量数据结构和函数。用得最多的pandas对象 DataFrame,它是一个面向列(column-oriented)的二维表构造Series,一个一维的标签化数组对象。pandas兼具NumPy高性能的数组计算性能以及电子表格和关系型数据库(如SQL)灵便的数据处理性能。它提供了简单精密的索引性能,能更加便捷地实现重塑、切片和切块、聚合以及选取数据子集等操作。 matplotlibmatplotlib是最风行的用于绘制图表和其它二维数据可视化的Python库。 SciPySciPy是一组专门解决科学计算中各种规范问题域的包的汇合,次要包含上面这些包: scipy.integrate:数值积分例程和微分方程求解器。scipy.linalg:扩大了由numpy.linalg提供的线性代数例程和矩阵合成性能。scipy.optimize:函数优化器(最小化器)以及根查找算法。scipy.signal:信号处理工具。scipy.sparse:稠密矩阵和稠密线性系统求解器。scipy.special:SPECFUN(这是一个实现了许多罕用数学函数(如伽玛函数)的Fortran库)的包装器。scipy.stats:规范间断和离散概率分布(如密度函数、采样器、间断散布函数等)、各种统计测验办法,以及更好的描述统计法。scikit-learn2010年诞生以来,scikit-learn成为了Python的通用机器学习工具包。 子模块包含: 分类:SVM、近邻、随机森林、逻辑回归等等。回归:Lasso、岭回归等等。聚类:k-均值、谱聚类等等。降维:PCA、特征选择、矩阵合成等等。选型:网格搜寻、穿插验证、度量。预处理:特征提取、标准化。statsmodels一个统计分析包,蕴含经典统计学和经济计量学的算法。 回归模型:线性回归,狭义线性模型,强壮线性模型,线性混合效应模型等等。方差分析(ANOVA)。工夫序列剖析:AR,ARMA,ARIMA,VAR和其它模型。非参数办法: 核密度估计,核回归。统计模型后果可视化。statsmodels更关注与统计推断,提供不确定预计和参数p-值。相同的,scikit-learn重视预测。 留神:当应用conda和pip二者安装包时,千万不要用pip降级conda的包,这样会导致环境产生问题。当应用Anaconda或Miniconda时,最好首先应用conda进行降级。常见的引入常规最佳引入形式如下: import numpy as npimport matplotlib.pyplot as pltimport pandas as pdimport seaborn as snsimport statsmodels as sm不倡议间接引入相似NumPy这种大型库的全部内容(from numpy import *)。

April 5, 2023 · 1 min · jiezi

关于pandas:pandas简单操作

因为须要用到pandas解决一些简略数据,记录一下应用的函数和思路: 1、pandas读取csv数据csv是gb2312编码,之前pandas始终没有代码提醒,不晓得怎么制订read_csv的编码方式,于是用open函数指定gb2312编码关上后,再把后果送入padnas,这样能解决不能解析的编码问题。 with open("金匮名医验案精选(900多则).csv","r", encoding="gb2312") as f: df = pd.read_csv(f)起初发现,能够间接在read_csv()中指定编码方式: df = pd.read_csv('xxy_yang.csv', encoding="gbk")2、pandas行列读取操作两个次要办法:依照index索引操作df.iloc(),依照行、列名进行操作的df.loc()对于这个一个数据表: import pandas as pddata = {'人名': ['小明', '小红', '张三', '李四'], '出世年份': ['2000', '2001', '2002', '2003'], '高考分数': ['630', '590', '600', '520'], '月薪': ['5200', '3900', '4500', '3500']}df = pd.DataFrame(data, columns=['人名', '出世年份', '高考分数', '月薪', '年终奖'], index=['one', 'two', 'three', 'four'])df['年终奖'] = ['9800', '9200', '9500', '9000']print("行索引:{}".format(list(df.index)))print("列索引:{}".format(list(df.columns)))print(df.index[1:3])print(df.columns[1])print(df.columns[1:3])print(df)运行后果为:依照index索引操作df.iloc()例如: df.iloc[1, 3] # 按坐标取(第二行第四列)df.iloc[[1], [3]] # 按坐标取(第二行第四列)df.iloc[:, 1] # 按地位取(任意行第二列)df.iloc[:, [1, 3]] # 按地位取不间断列数据(任意行第二列,第四列)df['人名']df.人名按行、列名操作如: print(df.loc['two'])print(df.loc['two', '人名'])print(df.loc['two':'three'])print(df.loc[['one', 'three']])print(df.loc[['one', 'three'], ['人名', '出世年份']])参考文献:pandas读取行列数据-具体介绍(间断&不间断)https://blog.csdn.net/in546/a... ...

December 22, 2022 · 1 min · jiezi

关于pandas:全自动化数据洞察数据分布对比可视化⛵

本文介绍如何应用 Pandas Profiling 的比拟报告性能,剖析两个数据集的散布差别,实现数据摸索剖析 (EDA) 的残缺流程,为后续剖析做筹备。 作者:韩信子@ShowMeAI 数据分析实战系列:https://www.showmeai.tech/tutorials/40 本文地址:https://www.showmeai.tech/article-detail/411 申明:版权所有,转载请分割平台与作者并注明出处 珍藏ShowMeAI查看更多精彩内容 引言 可视化是EDA的根底。当面对一个新的、未知的数据集时,视觉查看使咱们可能理解可用的信息,绘制一些无关数据的模式,并诊断出咱们可能须要解决的几个问题。在这方面,Pandas Profiling 始终是每个数据科学家工具箱中不可或缺的瑞士刀,能够帮忙咱们疾速生成数据摘要报告,包含数据概览、变量属性、数据分布、反复值和其余指标。它可能在可视化中出现这些信息,以便咱们更好地了解数据集。但如果咱们可能比拟两个数据集呢,有没有疾速的形式能够实现? 在本篇博客文章中,ShowMeAI将介绍如何利用 Pandas Profiling 的比拟报告性能来晋升数据摸索剖析 (EDA) 流程。咱们会介绍到如何应用 Pandas Profiling 比拟报告性能来比拟两个不同的数据集,这能够帮忙咱们更快地比照剖析数据,获取散布差别,为后续做筹备。 咱们本次用到的数据集是 Kaggle 的 HCC 数据集,大家能够通过 ShowMeAI 的百度网盘地址下载。 实战数据集下载(百度网盘):公众号『ShowMeAI钻研核心』回复『实战』,或者点击 这里 获取本文 [[42]Pandas Profiling:应用高级EDA工具比照剖析2个数据集](https://www.showmeai.tech/art...) 『HCC 数据集』 ⭐ ShowMeAI官网GitHub:https://github.com/ShowMeAI-Hub 对于更多数据自动化摸索工具,能够参考ShowMeAI过往文章 自动化数据分析 (EDA) 工具库大全。 全自动数据EDA工具 Pandas Profiling 性能回顾咱们回顾一下 Pandas Profiling 的装置与应用形式: # 通过pip装置pip install pandas-profiling==3.5.0如果咱们须要对 hcc 数据集进行剖析,参考代码如下: import pandas as pdfrom pandas_profiling import ProfileReport# Read the HCC Datasetdf = pd.read_csv("hcc.csv")# Produce the data profiling reportoriginal_report = ProfileReport(df, title='Original Data')original_report.to_file("original_report.html")咱们会失去十分清晰的数据分析后果报告,如下是报告的头部信息: ...

December 16, 2022 · 1 min · jiezi

关于pandas:Pandas中你一定要掌握的时间序列相关高级功能-⛵

本文解说Pandas工具库几个外围函数,能高效解决工夫序列:resample、shift、rolling。帮你得心应手解决工夫序列数据! 作者:韩信子@ShowMeAI 数据分析实战系列:https://www.showmeai.tech/tutorials/40 本文地址:https://www.showmeai.tech/article-detail/389 申明:版权所有,转载请分割平台与作者并注明出处 珍藏ShowMeAI查看更多精彩内容 Pandas 是大家都十分相熟的数据分析与解决工具库,对于结构化的业务数据,它能很不便地进行各种数据分析和数据操作。但咱们的数据中,常常会存在对应工夫的字段,很多业务数据也是工夫序组织,很多时候咱们不可避免地须要和工夫序列数据打交道。其实 Pandas 中有十分好的工夫序列解决办法,然而因为应用并不特地多,很多基础教程也会略过这一部分。 在本篇内容中,ShowMeAI对 Pandas 中解决工夫的外围函数办法进行解说。置信大家学习过后,会在解决工夫序列型数据时,更得心应手。 数据分析与解决的残缺常识技能,大家能够参考ShowMeAI制作的工具库速查表和教程进行学习和疾速应用。 数据迷信工具库速查表 | Pandas 速查表 图解数据分析:从入门到精通系列教程 工夫序列工夫序列是指将同一统计指标的数值按其产生的工夫先后顺序排列而成的数列。简略说来,工夫序列是随着工夫的推移记录某些取值,比如说商店一年的销售额(依照月份从1月到12月)。 Pandas 工夫序列解决咱们要理解的第一件事是如何在 Pandas 中创立一组日期。咱们能够应用date_range()创立任意数量的日期,函数须要你提供起始工夫、工夫长度和工夫距离。 # 构建时长为7的工夫序列pd.date_range("2022-01-01", periods=7, freq='D')# 输入# DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04','2022-01-05', '2022-01-06', '2022-01-07'], dtype='datetime64[ns]', freq='D')留神到下面的频率可用freq来设置:最常见的是'W'每周,'D'是每天,'M'是月末,'MS'是月开始。 上面咱们创立一个蕴含日期和销售额的工夫序列数据,并将日期设置为索引。 # 设置随机种子,能够复现np.random.seed(12)# 构建数据集df = pd.DataFrame({ 'date': pd.date_range("2022-01-01", periods=180, freq='D'), 'sales': np.random.randint(1000, 10000, size=180)}) # 设置索引df = df.set_index('date') 留神,咱们要不便地对工夫序列进行解决,一个很重要的先序工作是将日期作为索引,咱们后面曾经实现这个工作了。 重采样Pandas 中很重要的一个外围性能是resample,从新采样,是对原样本重新处理的一个办法,是一个对惯例工夫序列数据从新采样和频率转换的便捷的办法。 办法的格局是: DataFrame.resample(rule, how=None, axis=0, fill_method=None, closed=None, label=None, convention='start',kind=None, loffset=None, limit=None, base=0)外围的参数rule是字符串,示意采样的频度。如下代码,在resample后接的mean是示意依照月度求均匀。 ...

November 28, 2022 · 1 min · jiezi

关于pandas:Pandas-数据显示不全快来了解这些设置技巧-⛵

作者:韩信子@ShowMeAI 数据分析实战系列:http://www.showmeai.tech/tutorials/40 本文地址:http://www.showmeai.tech/article-detail/285 申明:版权所有,转载请分割平台与作者并注明出处 珍藏ShowMeAI查看更多精彩内容 Pandas 数据显示的问题 咱们在利用 Python 进行数据分析开掘和机器学习时,最罕用的工具库就是 Pandas,它能够帮忙咱们快捷地进行数据处理和剖析。 对 Pandas 不相熟的同学,肯定要学习下这个宝藏工具库哦!ShowMeAI 给大家做了一个详尽的教程,能够在 Python 数据分析教程 中查看,咱们同时也制作了 Pandas速查表,不便大家疾速查找须要的性能。如果你喜爱跟着视频学习,那么举荐B站这个 疾速实战教程。但在应用 Pandas 时,咱们常常会遇到像上面这样一些问题,它很影响咱们查看数据理解详情。 长文本无奈显示全对于十分长的字段可能显示不全,如下图中,URL 被缩短显示。 迷信计数法显示失去细节Pandas 默认应用『迷信计数法』显示大浮点数,例如 1000000.5 显示为 1.000e+06 。对于数值较大的数字,就可能有如下的显示,这导致咱们看不到具体数值。 ![](https://p3-juejin.byteimg.com...e" width="30%" referrerpolicy="no-referrer"> 小数位精度不统一对于浮点型的字段列,Pandas 可能有不同的位精度。例如下图中,col_1 准确到小数点后一位,而 col_2 准确到小数点后三位。有时候精度的不统一可能会有信息的差别。 在本篇内容中,ShowMeAI 将介绍如何应用 Pandas 自定义设置来解决诸如上述的问题。次要的设置包含上面内容: 自定义要显示的行数自定义要显示的列数自定义列宽使浮点列之间的小数位精度保持一致禁用迷信记数法其余用法留神:以上设置仅更改数据的显示出现形式,理论并不会影响Dataframe存储的数据。 Pandas自定义显示设置 自定义显示行数打印大 Dataframe(行列数很多的数据)时,Pandas 默认显示前 5 行和后 5 行,如下图所示。 咱们能够通过设置显示选项 display.max_rows 来更改要显示的行数,比方咱们将其设置为4。 pd.set_option("diaply.max_row", 4)df 咱们能够应用重置选项 pd.reset_option("display.max_rows") 复原默认行数显示设置。 自定义显示列数同样的情理,咱们能够通过设置 display.max_columns 自定义输入 Dataframe 时要显示的列数。 ...

August 5, 2022 · 1 min · jiezi

关于pandas:Pandas-变量类型转换的-6-种方法

一、变量类型及转换对于变量的数据类型而言,Pandas除了数值型的int 和 float类型外,还有object ,category,bool,datetime类型。 另外,空值类型作为一种非凡类型,须要独自解决。 数据处理的过程中,常常须要将这些类型进行相互转换,上面介绍一些变量类型转换的罕用办法。 1、查问变量类型在数据处理的过程中,针对不同的数据类型会有不同的解决办法,比方数值型能够做加减乘除,然而字符型、工夫类型就须要其它解决办法。为此,咱们首先须要将各种数据类型进行辨别,而后再别离解决。 pandas中select_dtype函数能够特色变量进行疾速分类,具体用法如下: DataFrame.select_dtypes(include=None, exclude=None) include:列表,想要留下的数据类型,比方float64,int64,bool,object等exclude:列表,须要排除的数据类型,同上。df = pd.DataFrame({'a': [1, 2] * 3,                   'b': [True, False] * 3,                   'c': [1.0, 2.0] * 3,                   'd': ['a','b']*3})# 筛选float和int的数值类型变量num_list = df.select_dtypes(include=['float','int64']).columns.tolist()# 筛选ojbect字符型的数值类型变量obj_list = df.select_dtypes(include=['object']).columns.tolist()print(obj_list)print(num_list)>> ['d']>> ['a', 'c']include和exclude也能够组合应用筛选。 如果想要查看所有变量的数据类型,能够通过info疾速查看,如下: df.info()>><class 'pandas.core.frame.DataFrame'>RangeIndex: 6 entries, 0 to 5Data columns (total 4 columns): #   Column  Non-Null Count  Dtype  ---  ------  --------------  -----   0   a       6 non-null      int64   1   b       6 non-null      bool    2   c       6 non-null      float64 3   d       6 non-null      object dtypes: bool(1), float64(1), int64(1), object(1)memory usage: 278.0+ bytes2、转换数值类型数值类型包含int和float。 转换数据类型比拟通用的办法能够用astype进行转换。 pandas中有种十分便当的办法to_numeric()能够将其它数据类型转换为数值类型。 pandas.to_numeric(arg, errors='raise', downcast=None) arg:被转换的变量,格局能够是list,tuple,1-d array,Serieserrors:转换时遇到谬误的设置,ignore, raise, coerce,上面例子中具体解说downcast:转换类型降级设置,比方整型的有无符号signed/unsigned,和浮点float上面例子中,s是一列数据,具备多种数据类型,当初想把它转换为数值类型。 import pandas as pdimport numpy as nps = pd.Series(['boy', '1.0', '2019-01-02', 1, False, None, pd.Timestamp('2018-01-05')])# 默认错位格局为raise,遇到非数字字符串类型报错pd.to_numeric(s, errors='raise')  # 错位格局为ignore,只对数字字符串转换, 其余类型一律漠视不转换, 蕴含工夫类型pd.to_numeric(s, errors='ignore') # 将工夫字符串和bool类型强制转换为数字, 其余均转换为NaNpd.to_numeric(s, errors='coerce')   # downcast 能够进一步转化为int或者floatpd.to_numeric(s) # 默认float64类型pd.to_numeric(s, downcast='signed') # 转换为整型4、转换字符类型数字转字符类型非常简单,能够简略的应用str间接转换。 df = pd.DataFrame({'year': [2015, 2016],                   'month': [2, 3],                   'day': [4, 5]})df['month'] = df['month'].map(str) df.info()>><class 'pandas.core.frame.DataFrame'>RangeIndex: 2 entries, 0 to 1Data columns (total 3 columns): #   Column  Non-Null Count  Dtype ---  ------  --------------  -----  0   year    2 non-null      int64  1   month   2 non-null      object 2   day     2 non-null      int64 dtypes: int64(2), object(1)memory usage: 176.0+ bytes此外这里再延长一下,去掉字符类型的办法eval。 比方,当咱们遇到'[1,2,3]'这种状况的时候,咱们理论想获取外面的列表,然而当初却是个字符串类型,咱们能够应用eval函数将''这个外套间接去掉,去掉后主动转换成外面数据类型。 a = '[1,2,3]'type(a) >> streval(a)>> [1, 2, 3]5、转换工夫类型应用to_datetime函数将数据转换为日期类型,用法如下: pandas.to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False, utc=None, box=True, format=None, exact=True, unit=None, infer_datetime_format=False, origin='unix') 参数比拟多,罕用的就是format,依照指定的字符串strftime格局解析日期,个别状况下该函数能够间接主动解析成日期类型。 # 对整个dataframe转换,将年月日几列主动合并为日期df = pd.DataFrame({'year': [2015, 2016],                   'month': [2, 3],                   'day': [4, 5]}) df>> year month day0 2015 2 41 2016 3 5pd.to_datetime(df)>>0   2015-02-041   2016-03-05dtype: datetime64[ns]# 对单列转换日期类型df1 = pd.DataFrame({'appl_tm':['20220401','20220402','20220403'],                    'appl_tm1':['2012.03.04','2021.09.04','2031.06.05']})>>df1    appl_tm     appl_tm10 20220401 2012.03.041 20220402 2021.09.042 20220403 2031.06.05 df1['appl_tm'] = pd.to_datetime(df1['appl_tm'])df1['appl_tm1'] = pd.to_datetime(df1['appl_tm1'], format='%Y.%m.%d')>>df1    appl_tm     appl_tm10 2022-04-01 2012-03-041 2022-04-02 2021-09-042 2022-04-03 2031-06-05转换为日期类型后,就能够对日期应用series.dt.办法进行更简单的筛选和查问了。 # 筛选2021年的日期,month和day也是同理df1['appl_tm1'].dt.year == 2021>>0    False1     True2    FalseName: appl_tm1, dtype: bool df1[df1['appl_tm1'].dt.year == 2021]>>    appl_tm     appl_tm11 2022-04-02 2021-09-046、转换category类型category类型在pandas中的出场率并不是很高,个别在不思考优化效率时,会用其它类型代替。但如果须要转换category类型,能够间接应用astype实现。 df = pd.DataFrame({'year': [2015, 2016],                   'month': [2, 3],                   'day': [4, 5]}) df['year'] = df['year'].astype('category')df.info()>><class 'pandas.core.frame.DataFrame'>RangeIndex: 2 entries, 0 to 1Data columns (total 3 columns): #   Column  Non-Null Count  Dtype   ---  ------  --------------  -----    0   year    2 non-null      category 1   month   2 non-null      int64    2   day     2 non-null      int64   dtypes: category(1), int64(2)memory usage: 258.0 byte对于category类型的具体应用办法,能够参考这篇文章:category分类变量的应用办法 7、智能类型转换convert_dtypes下面介绍的均为手动一对一的变量类型转换,pandas中还提供了一种智能转换的办法convert_dtypes,应用它能够无脑主动实现转换。 默认状况下,convert_dtypes将尝试将Series或DataFrame中的每个Series转换为反对的dtypes,它能够对Series和DataFrame都间接应用。 该办法的参数如下: infer_objects:默认为True,是否应将对象dtypes转换为最佳类型convert_string:默认为True,对象dtype是否应转换为StringDtype()convert_integer:默认为True,如果可能,是否能够转换为整数扩大类型convert_boolean :默认为True,对象dtype是否应转换为BooleanDtypes()convert_floating :默认为True,如果可能,是否能够转换为浮动扩大类型。如果convert_integer也为True,则如果能够将浮点数忠诚地转换为整数,则将优先思考整数dtype上面看一组示例。 通过后果能够看到,变量都是是创立时默认的类型。但其实变量是有整数、字符串、布尔的,其中有的还存在空值。 # 对整个dataframe间接转换>>> dfn = df.convert_dtypes()>>> dfn   a  b      c     d     e      f0  1  x   True     h    10   <NA>1  2  y  False     i  <NA>  100.52  3  z   <NA>  <NA>    20  200.0>>> dfn.dtypesa      Int32b     stringc    booleand     stringe      Int64f    Float64dtype: object疏忽了空值的影响,变量类型曾经主动转换为咱们想要的了。 对Series的转换也是一样的。上面的Seires中因为存在nan空值所以类型为object。 # Series 变量类型转换s = pd.Series(["a", "b", np.nan])>>> s0      a1      b2    NaNdtype: object# 通过convert_dtypes胜利转换为String>>> s.convert_dtypes()0       a1       b2    <NA>dtype: string如果将来减少了新类型,convert_dtypes办法也会同步更新,并反对新的变量类型。 以上就是本次分享的所有内容,如果你感觉文章还不错,欢送关注公众号:Python编程学习圈,每日干货分享,发送“J”还可支付大量学习材料,内容笼罩Python电子书、教程、数据库编程、Django,爬虫,云计算等等。或是返回编程学习网,理解更多编程技术常识。

July 15, 2022 · 1 min · jiezi

关于pandas:4款Pandas自动数据分析神器

咱们做数据分析,在第一次拿到数据集的时候,个别会用统计学或可视化办法来理解原始数据。 理解列数、行数、取值散布、缺失值、列之间的相干关系等等,这个过程叫做 EDA(Exploratory Data Analysis,探索性数据分析)。 如果你当初做EDA还在用pandas一行行写代码,那么福音来了! 目前曾经有很多EDA工具能够主动产出根底的统计数据和图表,能为咱们节俭大量工夫。 本文会比照介绍 4 款罕用的EDA工具,最初一款绝了,齐全是摈弃代码的节奏。 正式介绍这些工具之前,先来加载数据集 import numpy as npimport pandas as pdiris = pd.read_csv('iris.csv')iris iris是上面用到的数据集,是一个150行 * 4列的 DataFrame。 1. PandasGUIPandasGUI提供数据预览、筛选、统计、多种图表展现以及数据转换。 # 装置# pip install pandasguifrom pandasgui import showshow(iris) PandasGUI操作界面 PandasGUI更偏重数据展现,提供了10多种图表,通过可视的形式配置。 但数据统计做的比较简单,没有提供缺失值、相关系数等指标,数据转换局部也只凋谢了一小部分接口。 2. Pandas ProfilingPandas Profiling 提供了整体数据详情、每列的详情、列之间的关图、列之间的相关系数。 # 装置:# pip install -U pandas-profiling# jupyter nbextension enable --py widgetsnbextensionfrom pandas_profiling import ProfileReportprofile = ProfileReport(iris, title='iris Pandas Profiling Report', explorative=True)profile Pandas Profiling操作界面 每列的详情包含:缺失值统计、去重计数、最值、平均值等统计指标和取值散布的柱状图。 列之间的相关系数反对Spearman、Pearson、Kendall 和 Phik 4 种相关系数算法。 与 PandasGUI 相同,Pandas Profiling没有丰盛的图表,但提供了十分多的统计指标以及相关系数。 3. SweetvizSweetviz与Pandas Profiling相似,提供了每列具体的统计指标、取值散布、缺失值统计以及列之间的相关系数。 # 装置# pip install sweetvizimport sweetviz as svsv_report = sv.analyze(iris)sv_report.show_html() Sweetviz操作界面 Sweetviz还有有一个十分好的个性是反对不同数据集的比照,如:训练数据集和测试数据集的比照。 Sweetviz数据集比照 蓝色和橙色代表不同的数据集,通过比照能够清晰发现数据集之前的差别。 4. dtale最初重磅介绍dtale,它不仅提供丰盛图表展现数据,还提供了很多交互式的接口,对数据进行操作、转换。 dtale操作界面 dtale的性能次要分为三局部:数据操作、数据可视化、高亮显示。 4.1 数据操作(Actions)dtale将pandas的函数包装成可视化接口,能够让咱们通过图形界面形式来操作数据。 # pip install dtaleimport dtaled = dtale.show(iris)d.open_browser() Actions 右半局部图是右边图的中文翻译,用的是 Chrome 主动翻译,有些不是很精确。 举一个数据操作的例子。 Summarize Data 上图是Actions菜单中Summarize Data的性能,它提供了对数据集汇总操作的接口。 上图咱们抉择依照species列分组,计算sepal_width列的平均值,同时能够看到左下角dtale曾经主动为该操作生成了pandas代码。 4.2 数据可视化(Visualize)提供比拟丰盛的图表,对每列数据详情、反复行、缺失值、相关系数进行统计和展现。 Visualize 举一个数据可视化的例子。 ...

July 14, 2022 · 1 min · jiezi

关于pandas:Pandas-GroupBy-深度总结

明天,咱们将探讨如何在 Python 的 Pandas 库中创立 GroupBy 对象以及该对象的工作原理。咱们将具体理解分组过程的每个步骤,能够将哪些办法利用于 GroupBy 对象上,以及咱们能够从中提取哪些有用信息 不要再张望了,一起学起来吧 应用 Groupby 三个步骤首先咱们要晓得,任何 groupby 过程都波及以下 3 个步骤的某种组合: 依据定义的规范将原始对象分成组对每个组利用某些函数整合后果让我先来大抵浏览下明天用到的测试数据集 import pandas as pdimport numpy as nppd.set_option('max_columns', None)df = pd.read_csv('complete.csv')df = df[['awardYear', 'category', 'prizeAmount', 'prizeAmountAdjusted', 'name', 'gender', 'birth_continent']]df.head()Output: awardYear category prizeAmount prizeAmountAdjusted name gender birth_continent0 2001 Economic Sciences 10000000 12295082 A. Michael Spence male North America1 1975 Physics 630000 3404179 Aage N. Bohr male Europe2 2004 Chemistry 10000000 11762861 Aaron Ciechanover male Asia3 1982 Chemistry 1150000 3102518 Aaron Klug male Europe4 1979 Physics 800000 2988048 Abdus Salam male Asia将原始对象拆分为组在这个阶段,咱们调用 pandas DataFrame.groupby() 函数。咱们应用它依据预约义的规范将数据分组,沿行(默认状况下,axis=0)或列(axis=1)。换句话说,此函数将标签映射到组的名称。 ...

June 29, 2022 · 10 min · jiezi

关于pandas:Pandas缺失值处理超强讲解

本篇详解pandas中缺失值(Missing data handling)解决罕用操作。 缺失值解决罕用于数据分析数据荡涤阶段; Pandas中将如下类型定义为缺失值: NaN: ‘’, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’,‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘<NA>’, ‘N/A’, ‘NA’,‘NULL’, ‘NaN’, ‘n/a’, ‘nan’, ‘null’,None 1、pandas中缺失值注意事项pandas和numpy中任意两个缺失值不相等(np.nan != np.nan)下图中两个NaN不相等: In [224]: df1.iloc[3:,0].values#取出'one'列中的NaNOut[224]: array([nan])In [225]: df1.iloc[2:3,1].values#取出'two'列中的NaNOut[225]: array([nan])In [226]: df1.iloc[3:,0].values == df1.iloc[2:3,1].values#两个NaN值不相等Out[226]: array([False])pandas读取文件时那些值被视为缺失值NaN: ‘’, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’,‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘<NA>’, ‘N/A’, ‘NA’,‘NULL’, ‘NaN’, ‘n/a’, ‘nan’, ‘null’,None2、pandas缺失值操作pandas.DataFrame中判断那些值是缺失值:isna办法#定义一个试验DataFrameIn [47]: d = {'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}In [48]: df = pd.DataFrame(d)In [49]: dfOut[49]:   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0In [120]: df.isna()#返回形态一样的bool值填充DataFrameOut[120]:     one    twoa  False  Falseb  False  Falsec  False  Falsed   True  Falsepandas.DataFrame中删除蕴含缺失值的行:dropna(axis=0)In [67]: dfOut[67]:   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0In [68]: df.dropna()#默认axis=0Out[68]:   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0pandas.DataFrame中删除蕴含缺失值的列:dropna(axis=1)In [72]: df.dropna(axis=1)Out[72]:   twoa  1.0b  2.0c  3.0d  4.0pandas.DataFrame中删除蕴含缺失值的列和行:dropna(how='any')In [97]: df['three']=np.nan#新增一列全为NaNIn [98]: dfOut[98]:   one  two  threea  1.0  1.0    NaNb  2.0  2.0    NaNc  3.0  3.0    NaNd  NaN  4.0    NaNIn [99]: df.dropna(how='any')Out[99]:Empty DataFrame#全删除了Columns: [one, two, three]Index: []pandas.DataFrame中删除全是缺失值的行:dropna(axis=0,how='all')In [101]: df.dropna(axis=0,how='all')Out[101]:   one  two  threea  1.0  1.0    NaNb  2.0  2.0    NaNc  3.0  3.0    NaNd  NaN  4.0    NaNpandas.DataFrame中删除全是缺失值的列:dropna(axis=1,how='all')In [102]: df.dropna(axis=1,how='all')Out[102]:   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0pandas.DataFrame中应用某个值填充缺失值:fillna(某个值)In [103]: df.fillna(666)#应用666填充Out[103]:     one  two  threea    1.0  1.0  666.0b    2.0  2.0  666.0c    3.0  3.0  666.0d  666.0  4.0  666.0pandas.DataFrame中应用前一列的值填充缺失值:fillna(axis=1,method='ffill')#后一列填充为fillna(axis=1,method=bfill')In [109]: df.fillna(axis=1,method='ffill')Out[109]:   one  two  threea  1.0  1.0    1.0b  2.0  2.0    2.0c  3.0  3.0    3.0d  NaN  4.0    4.0pandas.DataFrame中应用前一行的值填充缺失值:fillna(axis=0,method='ffill')#后一行填充为fillna(axis=1,method=bfill')In [110]: df.fillna(method='ffill')Out[110]:   one  two  threea  1.0  1.0    NaNb  2.0  2.0    NaNc  3.0  3.0    NaNd  3.0  4.0    NaNpandas.DataFrame中应用字典传值填充指定列的缺失值In [112]: df.fillna({'one':666})#填充one列的NaN值Out[112]:     one  two  threea    1.0  1.0    NaNb    2.0  2.0    NaNc    3.0  3.0    NaNd  666.0  4.0    NaNIn [113]: df.fillna({'three':666})Out[113]:   one  two  threea  1.0  1.0  666.0b  2.0  2.0  666.0c  3.0  3.0  666.0d  NaN  4.0  666.0以上就是本次分享的所有内容,如果你感觉文章还不错,欢送关注公众号:Python编程学习圈,每日干货分享,发送“J”还可支付大量学习材料。或是返回编程学习网,理解更多编程技术常识。

June 29, 2022 · 1 min · jiezi

关于pandas:盘点66个Pandas函数轻松搞定数据清洗

明天咱们盘点66个Pandas函数合集,包含数据预览、数值数据操作、文本数据操作、行/列操作等等,波及“数据荡涤”的方方面面。 Pandas 是基于NumPy的一种工具,该工具是为解决数据分析工作而创立的。它提供了大量能使咱们疾速便捷地解决数据的函数和办法。 数据预览对于探索性数据分析来说,做数据分析前须要先看一下数据的总体详情。info()办法用来查看数据集信息,describe()办法将返回描述性统计信息,这两个函数大家应该都很相熟了。 describe办法默认只给出数值型变量的罕用统计量,要想对DataFrame中的每个变量进行汇总统计,能够将其中的参数include设为all。head()办法和tail() 办法则是别离显示数据集的前n和后n行数据。如果想要随机看N行的数据,能够应用sample()办法。 df.sample(3)输入: 如果要检查数据中各列的数据类型,能够应用.dtypes;如果想要值查看所有的列名,能够应用.columns。 df.columns输入: Index(['日期', '销量'], dtype='object')后面介绍的函数次要是读取数据集的数据信息,想要取得数据集的大小(长宽),能够应用.shape办法。 df.shape输入: (5, 2)另外,len()能够查看某列的行数,count()则能够查看该列值的无效个数,不蕴含有效值(Nan)。 缺失值与反复值Pandas荡涤数据时,判断缺失值个别采纳isnull()办法。此外,isnull().any()会判断哪些”列”存在缺失值,isnull().sum()用于将列中为空的个数统计进去。 df.isnull().any()输入: 日期 False销量 Truedtype: bool发现“销量”这列存在缺失值后,解决方法要么删除dropna() ,要么填充fillna()。 df.fillna(50)输入: Pandas荡涤数据时,判断反复值个别采纳duplicated()办法。如果想要间接删除反复值,能够应用drop_duplicates() 办法。此处较为常见,不再过多演示。 数值数据操作咱们在解决数据的时候,会遇到批量替换的状况,replace()是很好的解决办法。它既反对替换全副或者某一行,也反对替换指定的某个或指定的多个数值(用字典的模式),还能够应用正则表达式替换。 df["编号"].replace(r'BA.$', value='NEW', regex=True, inplace = True)输入: 在Pandas模块中, 调⽤rank()⽅法能够实现数据排名。 df["排名"] = df.rank(method="dense").astype("int")输入: rank()⽅法中的method参数,它有5个常⽤选项,能够帮忙咱们实现不同状况下的排名。 clip()办法,用于对超过或者低于某些数的数值进行截断[1],来保障数值在肯定范畴。比方每月的早退天数肯定是在0-31天之间。 df["早退天数"] = df["早退天数"].clip(0,31) 惟一值,unique()是以数组模式返回列的所有惟一值,而nunique()返回的是惟一值的个数。 df["gender"].unique()df["gender"].nunique()输入: 在数值数据操作中,apply()函数的性能是将一个自定义函数作用于DataFrame的行或者列;applymap()函数的性能是将自定义函数作用于DataFrame的所有元素。他们通常也与匿名函数lambda一起应用。 df["数量"].apply(lambda x: x+1)输入: 文本数据操作 之前咱们已经介绍过常常被人漠视的:Pandas 文本型数据处理。在对文本型的数据进行解决时,咱们会大量利用字符串的函数,来实现对一列文本数据进行操作[2]。 函数办法用法释义cat字符串的拼接contains判断某个字符串是否蕴含给定字符startswith/endswith判断某个字符串是否以...结尾/结尾get获取指定地位的字符串len计算字符串长度upper、lower英文大小写转换pad/center在字符串的右边、左边或左右两边增加给定字符repeat反复字符串几次slice_replace应用给定的字符串,替换指定的地位的字符split宰割字符串,将一列扩大为多列strip、rstrip、lstrip去除空白符、换行符findall利用正则表达式,去字符串中匹配,返回查找后果的列表extract、extractall承受正则表达式,抽取匹配的字符串(肯定要加上括号)举例: df.insert(2, "姓名",           df["姓"].str.cat(df["名"], sep=""))输入: df["手机号码"] = df["手机号码"].str.slice_replace(3,7,"*"*4)输入: df["地址"].str.extract("([\u4e00-\u9fa5]+)")  输入: 行/列操作数据荡涤时,会将带空值的行删除,此时DataFrame或Series类型的数据不再是间断的索引,能够应用reset_index()重置索引。 df.reset_index(drop=True)输入: rename()重命名用于更改行列的标签,即行列的索引。能够传入一个字典或者一个函数。在数据预处理中,比拟罕用。 df.rename(columns={'mark': 'sell'}, inplace=True)输入: 行列转置,咱们能够应用T属性取得转置后的DataFrame。 df.T输入: 删除行列,能够应用drop()。 df.drop(columns=["mark"])输入: 数据分析师在进行数据处理时常常会遇到长宽表互转的状况,这也是一道常见的数据分析面试题。 melt()办法能够将宽表转长表,即表格型数据转为树形数据。 df.melt(id_vars="姓名", var_name="科目", value_name="问题")输入: pivot()办法能够将长表转宽表,即树形数据转为表格型数据。 df.pivot(index='姓名', columns='科目', values='问题')输入: pivot()其实就是用 set_index()创立层次化索引,再用unstack()重塑 ...

June 15, 2022 · 1 min · jiezi

关于pandas:Pandas与SQL的超强结合爆赞

本文的所有演示数据,均是基于下方的四张表。对于下方各表之间的关联关系,我就不给大家阐明了,仔细观察字段名,应该就能够发现。 简介pandas中的DataFrame是一个二维表格,数据库中的表也是一个二维表格,因而在pandas中应用sql语句就显得瓜熟蒂落,pandasql应用SQLite作为其操作数据库,同时Python自带SQLite模块,不须要装置,便可间接应用。 这里有一点须要留神的是:应用pandasql读取DataFrame中日期格局的列,默认会读取年月日、时分秒,因而咱们要学会应用sqlite中的日期处理函数,不便咱们转换日期格局,下方提供sqlite中罕用函数大全,心愿对你有帮忙。 sqlite函数大全:http://suo.im/5DWraE 导入相干库: import pandas as pd  from pandasql import sqldf申明全局变量的2种形式在应用之前,申明该全局变量;一次性申明好全局变量;在应用之前,申明该全局变量df1 = pd.read_excel("student.xlsx")df2 = pd.read_excel("sc.xlsx")df3 = pd.read_excel("course.xlsx")df4 = pd.read_excel("teacher.xlsx")global df1global df2global df3global df4query1 = "select * from df1 limit 5"query2 = "select * from df2 limit 5"query3 = "select * from df3"query4 = "select * from df4"sqldf(query1)sqldf(query2)sqldf(query3)sqldf(query4)局部后果如下: 一次性申明好全局变量df1 = pd.read_excel("student.xlsx")  df2 = pd.read_excel("sc.xlsx")  df3 = pd.read_excel("course.xlsx")  df4 = pd.read_excel("teacher.xlsx")    pysqldf = lambda q: sqldf(q, globals())    query1 = "select * from df1 limit 5"  query2 = "select * from df2 limit 5"  query3 = "select * from df3"  query4 = "select * from df4"    sqldf(query1)  sqldf(query2)  sqldf(query3)  sqldf(query4)局部后果如下: 写几个简略的SQL语句查看sqlite的版本student = pd.read_excel("student.xlsx")  pysqldf = lambda q: sqldf(q, globals())  query1 = """      select sqlite_version(*)  """  pysqldf(query1)后果如下: where筛选student = pd.read_excel("student.xlsx")  pysqldf = lambda q: sqldf(q, globals())  query1 = """      select *       from student       where strftime('%Y-%m-%d',sage) = '1990-01-01'  """  pysqldf(query1)后果如下: 多表连贯student = pd.read_excel("student.xlsx")  sc = pd.read_excel("sc.xlsx")      pysqldf = lambda q: sqldf(q, globals())  query2 = """      select *      from student s      join sc on s.sid = sc.sid  """  pysqldf(query2)局部后果如下: 分组聚合student = pd.read_excel("student.xlsx")  sc = pd.read_excel("sc.xlsx")    pysqldf = lambda q: sqldf(q, globals())  query2 = """      select s.sname as 姓名,sum(sc.score) as 总分      from student s      join sc on s.sid = sc.sid      group by s.sname  """  pysqldf(query2)后果如下: union查问student = pd.read_excel("student.xlsx")  pysqldf = lambda q: sqldf(q, globals())  query1 = """      select *       from student       where strftime('%Y-%m',sage) = '1990-01'      union      select *       from student       where strftime('%Y-%m',sage) = '1990-12'  """  pysqldf(query1)后果如下: 以上就是本次分享的所有内容,想要理解更多 Python 常识欢送返回公众号:Python编程学习圈,每日干货分享,发送“J”还可支付大量学习材料。

June 13, 2022 · 1 min · jiezi

关于pandas:Pandas-第一轮零基础扫盲长期招收编程一对一教学VJiabcdefh

公众号原文首发:https://mp.weixin.qq.com/s/4RYfYc8_2vNxvq_B1bZrUA 为什么用 Pandas?你好,我是悦创。通过对 Numpy 的学习,咱们发现 Numpy 的性能的确弱小且易用。然而再弱小的工具也有其局限性。 例如 Numpy 是基于数组的运算,然而在理论工作中,咱们的数据元素会非常复杂,会同时蕴含文字格局、数字格局、工夫格局等,显然 Numpy就不实用了。 通常咱们说 Numpy 是基于数组格局构建的一个数组运算工具,而 Pandas 是基于 Numpy 构建的结构化数据处理工具。对 Pandas 来讲,数据格式失去了裁减,提供了工夫序列能力,并且可能同时包容多种数据格式,并且提供了灵便的缺失值解决工具,性能失去极大地拓展。 Pandas 罕用的数据结构有两种:Series 和 DataFrame 。其中 Series 是一个带有名称和索引的一维数组,而 DataFrame 则是用来示意多维的数组构造。 总结如下: 疾速高效的数据结构智能的数据处理能力不便的文件存取性能科研及商业利用宽泛对于 Pandas 有两种根底的数据结构,基本上咱们在应用的时候就是解决 Series 和 DataFrame。 Series:真正的数据是只有一列的,索引列咱们是不算进去的。索引数据A10B30C20D40DataFrame:好几个 Series 联合起来,也就是有好几列的数据联合起来。 电影评分评分人数0血观音7.9384781大佛普拉斯8.6581122华盛顿邮报8.2307733三块广告牌8.7250524装置 PandasWindows 零碎: pip install pandasMac 零碎: pip3 install pandas新建一个 Python 文件导入模块In [1]: import pandas as pdPandas 的根底类型1——Series创立一个 Series 类型的数据In [2]: data = pd.Series([1, 3, 5, 7])Series() 里间接填一个由数字组成的列表In [3]: list_data = [1, 3, 5, 7]In [4]: data = pd.Series(list_data) In [5]: dataOut[5]:0 11 32 53 7dtype: int64由后果咱们可知,右边把咱们的索引也列出来了,左边对应的数值也列出来了。底部通知你这个 Series 的数据类型 int64。「如果外面最低的数据类型是 float 那后果也会变成浮点数。」 ...

June 6, 2022 · 12 min · jiezi

关于pandas:你必须知道的Pandas-解析json数据的函数jsonnormalize

前言:Json数据介绍Json是一个利用及其宽泛的用来传输和替换数据的格局,它被利用在数据库中,也被用于API申请后果数据集中。 尽管它利用宽泛,机器很容易浏览且节俭空间,然而却不利于人来浏览和进一步做数据分析,因而通常状况下须要在获取json数据后,将其转化为表格格局的数据,以不便人来浏览和了解。 常见的Json数据格式有2种,均以键值对的模式存储数据,只是包装数据的办法有所差别: a. 个别JSON对象采纳{}将键值对数据括起来,有时候会有多层{} b. JSON对象列表采纳[]将JSON对象括起来,造成一个JSON对象的列表,JSON对象中同样会有多层{},也会有[]呈现,造成嵌套列表 这篇文章次要讲述pandas内置的Json数据转换方法json_normalize(),它能够对以上两种Json格局的数据进行解析,最终生成DataFrame,进而对数据进行更多操作。本文的次要解构如下: 解析一个最根本的Json- 解析一个带有多层数据的Json- 解析一个带有嵌套列表的Json- 当Key不存在时如何疏忽零碎报错- 应用sep参数为嵌套Json的Key设置分隔符- 为嵌套列表数据和元数据增加前缀- 通过URL获取Json数据并进行解析- 探索:解析带有多个嵌套列表的Jsonjson_normalize()函数参数解说 在进行代码演示前先导入相应依赖库,未装置pandas库的请自行装置(此代码在Jupyter Notebook环境中运行)。 from pandas import json_normalizeimport pandas as pd1. 解析一个最根本的Jsona. 解析个别Json对象a_dict = {<!-- -->    'school': 'ABC primary school',    'location': 'London',    'ranking': 2}pd.json_normalize(a_dict)输入后果为: b. 解析一个Json对象列表json_list = [    {<!-- -->'class': 'Year 1', 'student number': 20, 'room': 'Yellow'},    {<!-- -->'class': 'Year 2', 'student number': 25, 'room': 'Blue'}]pd.json_normalize(json_list)输入后果为: 2. 解析一个带有多层数据的Jsona. 解析一个有多层数据的Json对象json_obj = {<!-- -->    'school': 'ABC primary school',    'location': 'London',    'ranking': 2,    'info': {<!-- -->        'president': 'John Kasich',        'contacts': {<!-- -->            'email': {<!-- -->                'admission': 'admission@abc.com',                'general': 'info@abc.com'            },            'tel': '123456789',        }    }}pd.json_normalize(json_obj)输入后果为: 多层key之间应用点隔开,展现了所有的数据,这曾经解析了3层,上述写法和pd.json_normalize(json_obj, max_level=3)等价。 如果设置max_level=1,则输入后果为下图所示,contacts局部的数据会集成了一列 如果设置max_level=2,则输入后果为下图所示,contacts 下的email局部的数据会集成了一列 b. 解析一个有多层数据的Json对象列表json_list = [    {<!-- -->        'class': 'Year 1',        'student count': 20,        'room': 'Yellow',        'info': {<!-- -->            'teachers': {<!-- -->                'math': 'Rick Scott',                'physics': 'Elon Mask'            }        }    },    {<!-- -->        'class': 'Year 2',        'student count': 25,        'room': 'Blue',        'info': {<!-- -->            'teachers': {<!-- -->                'math': 'Alan Turing',                'physics': 'Albert Einstein'            }        }    }]pd.json_normalize(json_list)输入后果为: 若别离将max_level设置为2和3,则输入后果应别离是什么?请自行尝试~ 3. 解析一个带有嵌套列表的Jsonjson_obj = {<!-- -->    'school': 'ABC primary school',    'location': 'London',    'ranking': 2,    'info': {<!-- -->        'president': 'John Kasich',        'contacts': {<!-- -->            'email': {<!-- -->                'admission': 'admission@abc.com',                'general': 'info@abc.com'            },            'tel': '123456789',        }    },    'students': [        {<!-- -->'name': 'Tom'},        {<!-- -->'name': 'James'},        {<!-- -->'name': 'Jacqueline'}    ],}pd.json_normalize(json_obj)此例中students键对应的值是一个列表,应用[]括起来。间接采纳上述的办法进行解析,则失去的后果如下: students局部的数据并未被胜利解析,此时能够为record_path设置值即可,调用形式为pd.json_normalize(json_obj, record_path='students'),在此调用形式下,失去的后果只蕴含了name局部的数据。 若要减少其余字段的信息,则需为meta参数赋值,例如下述调用形式下,失去的后果如下: pd.json_normalize(json_obj, record_path='students', meta=['school', 'location', ['info', 'contacts', 'tel'], ['info', 'contacts', 'email', 'general']]) 4. 当Key不存在时如何疏忽零碎报错data = [    {<!-- -->         'class': 'Year 1',         'student count': 20,         'room': 'Yellow',        'info': {<!-- -->            'teachers': {<!-- -->                 'math': 'Rick Scott',                 'physics': 'Elon Mask',            }        },        'students': [            {<!-- --> 'name': 'Tom', 'sex': 'M' },            {<!-- --> 'name': 'James', 'sex': 'M' },        ]    },    {<!-- -->         'class': 'Year 2',         'student count': 25,         'room': 'Blue',        'info': {<!-- -->            'teachers': {<!-- -->                  # no math teacher                 'physics': 'Albert Einstein'            }        },        'students': [            {<!-- --> 'name': 'Tony', 'sex': 'M' },            {<!-- --> 'name': 'Jacqueline', 'sex': 'F' },        ]    },]pd.json_normalize(    data,     record_path =['students'],     meta=['class', 'room', ['info', 'teachers', 'math']])在class等于Year 2的Json对象中,teachers下的math键不存在,间接运行上述代码会报以下谬误,提醒math键并不总是存在,且给出了相应倡议:Try running with errors='ignore'。 增加errors条件后,从新运行得出的后果如下图所示,没有math键的局部应用NaN进行了填补。 pd.json_normalize(    data,     record_path =['students'],     meta=['class', 'room', ['info', 'teachers', 'math']],    errors='ignore') 5. 应用sep参数为嵌套Json的Key设置分隔符在2.a的案例中,能够留神到输入后果的具备多层key的数据列题目是采纳.对多层key进行分隔的,能够为sep赋值以更改分隔符。 json_obj = {<!-- -->    'school': 'ABC primary school',    'location': 'London',    'ranking': 2,    'info': {<!-- -->        'president': 'John Kasich',        'contacts': {<!-- -->          'email': {<!-- -->              'admission': 'admission@abc.com',              'general': 'info@abc.com'          },          'tel': '123456789',      }    }}pd.json_normalize(json_obj, sep='-&gt;')输入后果为: 6. 为嵌套列表数据和元数据增加前缀在3例的输入后果中,各列名均无前缀,例如name这一列不知是元数据解析失去的数据,还是通过student嵌套列表的的出的数据,因而为record_prefix和meta_prefix参数别离赋值,即可为输入后果增加相应前缀。 json_obj = {<!-- -->    'school': 'ABC primary school',    'location': 'London',    'ranking': 2,    'info': {<!-- -->        'president': 'John Kasich',        'contacts': {<!-- -->            'email': {<!-- -->                'admission': 'admission@abc.com',                'general': 'info@abc.com'            },            'tel': '123456789',        }    },    'students': [        {<!-- -->'name': 'Tom'},        {<!-- -->'name': 'James'},        {<!-- -->'name': 'Jacqueline'}    ],}pd.json_normalize(json_obj, record_path='students',                  meta=['school', 'location', ['info', 'contacts', 'tel'], ['info', 'contacts', 'email', 'general']],                  record_prefix='students-&gt;',                  meta_prefix='meta-&gt;',                  sep='-&gt;')本例中,为嵌套列表数据增加students-&gt;前缀,为元数据增加meta-&gt;前缀,将嵌套key之间的分隔符批改为-&gt;,输入后果为: 7. 通过URL获取Json数据并进行解析通过URL获取数据须要用到requests库,请自行装置相应库。 import requestsfrom pandas import json_normalize# 通过天气API,获取深圳近7天的天气url = 'https://tianqiapi.com/free/week'# 传入url,并设定好相应的paramsr = requests.get(url, params={<!-- -->"appid":"59257444", "appsecret":"uULlTGV9 ", 'city':'深圳'})# 将获取到的值转换为json对象result = r.json()df = json_normalize(result, meta=['city', 'cityid', 'update_time'], record_path=['data'])dfresult的后果如下所示,其中data为一个嵌套列表: {<!-- -->'cityid': '101280601', 'city': '深圳', 'update_time': '2021-08-09 06:39:49', 'data': [{<!-- -->'date': '2021-08-09',   'wea': '中雨转雷阵雨',   'wea_img': 'yu',   'tem_day': '32',   'tem_night': '26',   'win': '无继续风向',   'win_speed': '&lt;3级'},  {<!-- -->'date': '2021-08-10',   'wea': '雷阵雨',   'wea_img': 'yu',   'tem_day': '32',   'tem_night': '27',   'win': '无继续风向',   'win_speed': '&lt;3级'},  {<!-- -->'date': '2021-08-11',   'wea': '雷阵雨',   'wea_img': 'yu',   'tem_day': '31',   'tem_night': '27',   'win': '无继续风向',   'win_speed': '&lt;3级'},  {<!-- -->'date': '2021-08-12',   'wea': '多云',   'wea_img': 'yun',   'tem_day': '33',   'tem_night': '27',   'win': '无继续风向',   'win_speed': '&lt;3级'},  {<!-- -->'date': '2021-08-13',   'wea': '多云',   'wea_img': 'yun',   'tem_day': '33',   'tem_night': '27',   'win': '无继续风向',   'win_speed': '&lt;3级'},  {<!-- -->'date': '2021-08-14',   'wea': '多云',   'wea_img': 'yun',   'tem_day': '32',   'tem_night': '27',   'win': '无继续风向',   'win_speed': '&lt;3级'},  {<!-- -->'date': '2021-08-15',   'wea': '多云',   'wea_img': 'yun',   'tem_day': '32',   'tem_night': '27',   'win': '无继续风向',   'win_speed': '&lt;3级'}]}解析后的输入后果为: ...

May 30, 2022 · 1 min · jiezi

关于pandas:数据分析实际案例之pandas在泰坦尼特号乘客数据中的使用

简介1912年4月15日,号称永不沉没的泰坦尼克号因为和冰山相撞沉没了。因为没有足够的救济设施,2224个乘客中有1502个乘客不幸遇难。事变曾经产生了,然而咱们能够从泰坦尼克号中的历史数据中发现一些数据法则吗?明天本文将会率领大家灵便的应用pandas来进行数据分析。 泰坦尼特号乘客数据咱们从kaggle官网中下载了局部泰坦尼特号的乘客数据,次要蕴含上面几个字段: 变量名含意取值survival是否生还0 = No, 1 = Yespclass船票的级别1 = 1st, 2 = 2nd, 3 = 3rdsex性别 Age年龄 sibsp配偶信息 parch父母或者子女信息 ticket船票编码 fare船费 cabin客舱编号 embarked登录的港口C = Cherbourg, Q = Queenstown, S = Southampton下载下来的文件是一个csv文件。接下来咱们来看一下怎么应用pandas来对其进行数据分析。 应用pandas对数据进行剖析引入依赖包本文次要应用pandas和matplotlib,所以须要首先进行上面的通用设置: from numpy.random import randnimport numpy as npnp.random.seed(123)import osimport matplotlib.pyplot as pltimport pandas as pdplt.rc('figure', figsize=(10, 6))np.set_printoptions(precision=4)pd.options.display.max_rows = 20读取和剖析数据pandas提供了一个read_csv办法能够很不便的读取一个csv数据,并将其转换为DataFrame: path = '../data/titanic.csv'df = pd.read_csv(path)df咱们看下读入的数据: PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked 08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ38953Wirz, Mr. Albertmale27.0003151548.6625NaNS48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS58973Svensson, Mr. Johan Cervinmale14.00075389.2250NaNS68983Connolly, Miss. Katefemale30.0003309727.6292NaNQ78992Caldwell, Mr. Albert Francismale26.01124873829.0000NaNS89003Abrahim, Mrs. Joseph (Sophie Halaut Easu)female18.00026577.2292NaNC99013Davies, Mr. John Samuelmale21.020A/4 4887124.1500NaNS....................................40813003Riordan, Miss. Johanna Hannah""femaleNaN003349157.7208NaNQ40913013Peacock, Miss. Treasteallfemale3.011SOTON/O.Q. 310131513.7750NaNS41013023Naughton, Miss. HannahfemaleNaN003652377.7500NaNQ41113031Minahan, Mrs. William Edward (Lillian E Thorpe)female37.0101992890.0000C78Q41213043Henriksson, Miss. Jenny Lovisafemale28.0003470867.7750NaNS41313053Spector, Mr. WoolfmaleNaN00A.5. 32368.0500NaNS41413061Oliva y Ocana, Dona. Ferminafemale39.000PC 17758108.9000C105C41513073Saether, Mr. Simon Sivertsenmale38.500SOTON/O.Q. 31012627.2500NaNS41613083Ware, Mr. FrederickmaleNaN003593098.0500NaNS41713093Peter, Master. Michael JmaleNaN11266822.3583NaNC418 rows × 11 columns ...

February 24, 2022 · 3 min · jiezi

关于pandas:精选3种张炫酷的动态交互式图表Pandas一键生成通俗易懂

大家好! 明天来讲一下如何用一行代码在DataFrame数据集当中生成炫酷的动静交互式的图表,咱们先来介绍一下这次须要用到的模块cufflinks 模块的装置波及到装置,间接pip install即可 pip install cufflinks导入模块,并查看相干的配置咱们导入该模块,看一下目前的版本是在多少 cf.__version__output '0.17.3'目前该模块的版本曾经到了0.17.3,也是最新的版本,而后咱们最新版本反对能够绘制的图表有哪些 cf.help()output Use 'cufflinks.help(figure)' to see the list of available parameters for the given figure.Use 'DataFrame.iplot(kind=figure)' to plot the respective figureFigures: bar box bubble bubble3d candle choroplet distplot .......从下面的输入咱们能够看到,绘制图表大抵的语法是df.iplot(kind=图表名称)而如何咱们想要查看某个特定图表绘制时候的参数,例如柱状图bar参数有哪些,能够这么做 cf.help('bar')柱状图咱们先来看一下直方图图表的绘制,首先来创立一个数据集用于图表的绘制 df2 = pd.DataFrame({'Category':['A','B','C','D'],                    'Values':[95,56,70,85]})df2output   Category  Values0        A      951        B      562        C      703        D      85而后咱们来绘制直方图 df2.iplot(kind='bar',x='Category',y='Values',          xTitle = "Category",yTitle = "Values",          title = "直方图")output 其中的x参数下面填的是x轴下面对应的变量名,而y参数填的是y轴下面对应的变量名,咱们能够将绘制的图表以png的格局下载下来, 同时咱们也还能够对绘制的图表放大查看, 咱们再来看一下上面这组数据 df = pd.DataFrame(np.random.randn(100,4),columns='A B C D'.split())df.head()output           A         B         C         D0  0.612403 -0.029236 -0.595502  0.0277221  1.167609  1.528045 -0.498168 -0.2210602 -1.338883 -0.732692  0.935410  0.3387403  1.662209  0.269750 -1.026117 -0.8584724  1.387077 -0.839192 -0.562382 -0.989672咱们来绘制直方图的图表 df.head(10).iplot('bar')output 咱们也能够来绘制“重叠式”的直方图 df.head(10).iplot(kind='bar',barmode='stack')output 那么同样地,咱们也能够将直方图横过去来绘制 df.head(10).iplot(kind='barh',barmode='stack')output 折线图上面咱们来看一下折线图的绘制,咱们首先针对下面的df数据集各列做一个累加 df3 = df.cumsum()而后咱们来绘制折线图 df3.iplot()output 当然你也能够筛选出当中的几列而后来进行绘制,成果如下 df3[["A", "B"]].iplot()output 咱们也能够给折线图画一条拟合其走势的直线, df3['A'].iplot(bestfit = True,bestfit_colors=['pink'])output 这里咱们着重来介绍一个iplot()办法外面罕用的参数 kind:图表类型,默认的是scatter,散点类型,可供选择的类型还有bar(直方图)、box(箱型图)、heatmap(热力求)等等theme: 布局主题,能够通过cf.getThemes()来查看次要有哪些title: 图表的题目xTitle/yTitle: x或者y轴下面的轴名colors: 绘制图表时候的色彩subplots: 布尔值,绘制子图时候须要用到,默认为Falsemode: 字符串,绘图的模式,能够有lines、markers,也还有lines+markers和lines+text等模式size: 针对于散点图而言,次要用来调整散点的大小shape: 在绘制子图时候各个图的布局bargap: 直方图当中柱子之间的间隔barmode : 直方图的状态,stack(重叠式)、group(簇状)、overlay(笼罩)面积图从折线图到面积图的转变十分的简略,只须要将参数fill设置为True即可,代码如下 df3.iplot(fill = True)output

December 30, 2021 · 1 min · jiezi

关于pandas:Pandas学习笔记02处理数据实用操作

作者:幻好 起源:恒生LIGHT云社区 Pandas 是一个 Python 软件库,它提供了大量能使咱们疾速便捷地解决数据的函数和办法。在本文将次要介绍 Pandas 的实用数据处理操作。 系列文章: 【Pandas学习笔记01】弱小的剖析结构化数据的工具集 概述Pandas 是基于 NumPy 构建的库,在数据处理方面能够把它了解为 NumPy 加强版,同时 Pandas 也是一项开源我的项目。它基于 Cython,因而读取与解决数据十分快,并且还能轻松解决浮点数据中的缺失数据(示意为 NaN)以及非浮点数据。在本文中,根本数据集操作次要介绍了 CSV 与 Excel 的读写办法,根本数据处理次要介绍了缺失值及特色抽取,最初的 DataFrame 操作则次要介绍了函数和排序等办法。 数据集根底操作读取 CSV 格式文件中的数据集import pandas as pd# 形式1 df1 = pd.read_csv(“file.csv”)# 形式2df2 = pd.DataFrame.from_csv(“file.csv”)读取 Excel 格式文件中的数据集import pandas as pddf = pd.read_excel("file.xlsx")获取根本的数据集特色信息df.info()查问数据集根本统计信息print(df.describe())查问所有列的题目名称print(df.columns)应用 DataFrame 对象将数据写入 CSV 文件# 采纳逗号作为分隔符,且不带索引df.to_csv("data.csv", sep=",", index=False)数据集的解决首先定义一个 DataFrame 数据集: import pandas as pddf = pd.DataFrame(data = [['java',1],['python',2],['golang','3']],index = [1,2,3],columns = ['name','rank'])print(df)打印数据集: name rank1 java 12 python 23 golang 3查问数据操作应用df.loc[index, column] 对具体的行和列的数据进行查问# 查问指定行和列的数据df.loc[0,'name']#选取第0行到第1行,name列和rank列的数据df.loc[[0,1],['name','age']]#选取name列是M,name和rank列的数据df.loc[df['name']=='java',['name','rank']] 通过df['column_name'] 或df[row_start_index, row_end_index] 对整列或肯定范畴的行数据进行查问# 选取单列或多列df['name']df[['name','rank']] #第0行及之后的行df[0:] # 第1行到第2行(不含第3行)df[1:3] # 最初一行df[-1:] 减少数据操作向数据集中减少列数据:# 在第0列,加上 column 名称为 user_num,值为 user_num 的值user_num = ['100','89','70']df.insert(0,'user_num',user_num) # 默认在df最初一列加上column名称为 application,值为 application 的数据application = ['Web','AI','server']df['application'] = application向数据集中减少行数据:# 若df中没有index为“10”的这一行数据,则新增# 若df中曾经有index为“10”的这一行数据,则更新数据。df.loc[10] = ['php',10]# 向df中追加新的数据new_df = pd.DataFrame(index = True,columns = ['name','rank'])df = df.append(new_df,ignore_index = True) 批改数据操作批改列题目#只把’user_num’改为’users’,要把所有的列全写上,否则报错。df.columns = ['name', 'rank', 'users'] #只批改name,inplace若为True,间接批改df,否则,不批改df,只是返回一个批改后的数据。df.rename(columns = {'name':'Name'}, inplace = True) 批改数值# 批改index为‘0’,column为‘name’的那一个值为Cdf.loc[0, 'name'] = 'C' # 批改index为‘0’的那一行的所有值df.loc[0] = ['java', 1, '1000'] # 批改index为‘0’,column为‘name’的那一个值为Javadf.loc[0,['name','rank']] = ['Java'] # 替换缺失数据df.replace(to_replace=None, value=None)删除数据操作删除行数据# 删除index值为2和3的两行df.drop([2,3],axis = 0,inplace = False)删除列数据# 删除 name 列df.drop(['name'],axis = 1,inplace = False) del df['name'] # 删除 name 列,操作后,将删除的返回给new_dfnew_df = df.pop('age') 总结本文次要介绍 Pandas 工具集的实用操作,可能帮忙咱们解决日常数据处理的根本问题,后续将持续分享高阶技巧,敬请期待。 ...

November 26, 2021 · 1 min · jiezi

关于pandas:Pandas高级教程之时间处理

简介工夫应该是在数据处理中常常会用到的一种数据类型,除了Numpy中datetime64 和 timedelta64 这两种数据类型之外,pandas 还整合了其余python库比方 scikits.timeseries 中的性能。 工夫分类pandas中有四种工夫类型: Date times : 日期和工夫,能够带时区。和规范库中的 datetime.datetime 相似。Time deltas: 相对持续时间,和 规范库中的 datetime.timedelta 相似。Time spans: 由工夫点及其关联的频率定义的时间跨度。Date offsets:基于日历计算的工夫 和 dateutil.relativedelta.relativedelta 相似。咱们用一张表来示意: 类型标量class数组classpandas数据类型次要创立办法Date timesTimestampDatetimeIndexdatetime64[ns] or datetime64[ns, tz]to_datetime or date_rangeTime deltasTimedeltaTimedeltaIndextimedelta64[ns]to_timedelta or timedelta_rangeTime spansPeriodPeriodIndexperiod[freq]Period or period_rangeDate offsetsDateOffsetNoneNoneDateOffset看一个应用的例子: In [19]: pd.Series(range(3), index=pd.date_range("2000", freq="D", periods=3))Out[19]: 2000-01-01 02000-01-02 12000-01-03 2Freq: D, dtype: int64看一下下面数据类型的空值: In [24]: pd.Timestamp(pd.NaT)Out[24]: NaTIn [25]: pd.Timedelta(pd.NaT)Out[25]: NaTIn [26]: pd.Period(pd.NaT)Out[26]: NaT# Equality acts as np.nan wouldIn [27]: pd.NaT == pd.NaTOut[27]: FalseTimestampTimestamp 是最根底的工夫类型,咱们能够这样创立: ...

October 11, 2021 · 5 min · jiezi

关于pandas:python爬虫-Day-7

第一次补课--第七节课后csv写入与读取1. 写入文件(1)通过创立writer对象,应用列表的形式,次要用到两个办法:一个是writerow,每次写入一行;一个是writerows,每次写入多行,只需写入一次 import csvimport pandas as pd# 第一种写入形式 writerowperson =[ ('你猜', 18, 180), ('不猜', 20, 182), ('我猜', 22, 184),]# 表头header = ('name', 'age', 'height')# w-->写 如果office关上乱码了 须要改成utf-8-sig newline-->换行with open('person.csv', 'w', encoding='utf-8', newline='') as file_obj: writer = csv.writer(file_obj) writer.writerow(header) # 把表头写进去 for i in person: writer.writerow(i) # 把内容写进去# 第二种写入形式 writerowsperson =[ ('你猜', 18, 180), ('不猜', 20, 182), ('我猜', 22, 184),]header = ('name', 'age', 'height')with open('person2.csv', 'w', encoding='utf-8', newline='') as file_obj: writer = csv.writer(file_obj) writer.writerow(header) # 把表头写进去 writer.writerows(person) # 把内容写进去(2)通过创立DictWriter对象 即应用字典的形式写入数据 ...

August 30, 2021 · 2 min · jiezi

关于pandas:Pandas高级教程之统计方法

简介数据分析中常常会用到很多统计类的办法,本文将会介绍Pandas中应用到的统计办法。 变动百分百Series和DF都有一个pct_change() 办法用来计算数据变动的百分比。这个办法在填充NaN值的时候特地有用。 ser = pd.Series(np.random.randn(8))ser.pct_change()Out[45]: 0 NaN1 -1.2647162 4.1250063 -1.1590924 -0.0912925 4.8377526 -1.1821467 -8.721482dtype: float64serOut[46]: 0 -0.9505151 0.2516172 1.2895373 -0.2051554 -0.1864265 -1.0883106 0.1982317 -1.530635dtype: float64pct_change还有个periods参数,能够指定计算百分比的periods,也就是隔多少个元素来计算: In [3]: df = pd.DataFrame(np.random.randn(10, 4))In [4]: df.pct_change(periods=3)Out[4]: 0 1 2 30 NaN NaN NaN NaN1 NaN NaN NaN NaN2 NaN NaN NaN NaN3 -0.218320 -1.054001 1.987147 -0.5101834 -0.439121 -1.816454 0.649715 -4.8228095 -0.127833 -3.042065 -5.866604 -1.7769776 -2.596833 -1.959538 -2.111697 -3.7989007 -0.117826 -2.169058 0.036094 -0.0676968 2.492606 -1.357320 -1.205802 -1.5586979 -1.012977 2.324558 -1.003744 -0.371806Covariance协方差Series.cov() 用来计算两个Series的协方差,会疏忽掉NaN的数据。 ...

July 8, 2021 · 4 min · jiezi

关于pandas:Pandas高级教程之plot画图详解

简介python中matplotlib是十分重要并且不便的图形化工具,应用matplotlib能够可视化的进行数据分析,明天本文将会具体解说Pandas中的matplotlib利用。 根底画图要想应用matplotlib,咱们须要援用它: In [1]: import matplotlib.pyplot as plt如果咱们要从2020年1月1日开始,随机生成365天的数据,而后作图示意应该这样写: ts = pd.Series(np.random.randn(365), index=pd.date_range("1/1/2020", periods=365))ts.plot() 应用DF能够同时画多个Series的图像: df3 = pd.DataFrame(np.random.randn(365, 4), index=ts.index, columns=list("ABCD")) df3= df3.cumsum()df3.plot() 能够指定行和列应用的数据: df3 = pd.DataFrame(np.random.randn(365, 2), columns=["B", "C"]).cumsum()df3["A"] = pd.Series(list(range(len(df))))df3.plot(x="A", y="B"); 其余图像plot() 反对很多图像类型,包含bar, hist, box, density, area, scatter, hexbin, pie等,上面咱们别离举例子来看下怎么应用。 bar df.iloc[5].plot(kind="bar"); 多个列的bar: df2 = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])df2.plot.bar(); stacked bardf2.plot.bar(stacked=True); barhbarh 示意横向的bar图: df2.plot.barh(stacked=True); Histogramsdf2.plot.hist(alpha=0.5); boxdf.plot.box(); box能够自定义色彩: color = { ....: "boxes": "DarkGreen", ....: "whiskers": "DarkOrange", ....: "medians": "DarkBlue", ....: "caps": "Gray", ....: }df.plot.box(color=color, sym="r+"); ...

July 7, 2021 · 4 min · jiezi

关于pandas:Pandas高级教程之category数据类型

简介Pandas中有一种非凡的数据类型叫做category。它示意的是一个类别,个别用在统计分类中,比方性别,血型,分类,级别等等。有点像java中的enum。 明天给大家具体解说一下category的用法。 创立category应用Series创立在创立Series的同时增加dtype="category"就能够创立好category了。category分为两局部,一部分是order,一部分是字面量: In [1]: s = pd.Series(["a", "b", "c", "a"], dtype="category")In [2]: sOut[2]: 0 a1 b2 c3 adtype: categoryCategories (3, object): ['a', 'b', 'c']能够将DF中的Series转换为category: In [3]: df = pd.DataFrame({"A": ["a", "b", "c", "a"]})In [4]: df["B"] = df["A"].astype("category")In [5]: df["B"]Out[32]: 0 a1 b2 c3 aName: B, dtype: categoryCategories (3, object): [a, b, c]能够创立好一个pandas.Categorical ,将其作为参数传递给Series: In [10]: raw_cat = pd.Categorical( ....: ["a", "b", "c", "a"], categories=["b", "c", "d"], ordered=False ....: ) ....: In [11]: s = pd.Series(raw_cat)In [12]: sOut[12]: 0 NaN1 b2 c3 NaNdtype: categoryCategories (3, object): ['b', 'c', 'd']应用DF创立创立DataFrame的时候,也能够传入 dtype="category": ...

June 28, 2021 · 5 min · jiezi

关于pandas:Pandas高级教程之处理缺失数据

简介在数据处理中,Pandas会将无奈解析的数据或者缺失的数据应用NaN来示意。尽管所有的数据都有了相应的示意,然而NaN很显著是无奈进行数学运算的。 本文将会解说Pandas对于NaN数据的解决办法。 NaN的例子下面讲到了缺失的数据会被体现为NaN,咱们来看一个具体的例子: 咱们先来构建一个DF: In [1]: df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'], ...: columns=['one', 'two', 'three']) ...: In [2]: df['four'] = 'bar'In [3]: df['five'] = df['one'] > 0In [4]: dfOut[4]: one two three four fivea 0.469112 -0.282863 -1.509059 bar Truec -1.135632 1.212112 -0.173215 bar Falsee 0.119209 -1.044236 -0.861849 bar Truef -2.104569 -0.494929 1.071804 bar Falseh 0.721555 -0.706771 -1.039575 bar True下面DF只有acefh这几个index,咱们从新index一下数据: In [5]: df2 = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])In [6]: df2Out[6]: one two three four fivea 0.469112 -0.282863 -1.509059 bar Trueb NaN NaN NaN NaN NaNc -1.135632 1.212112 -0.173215 bar Falsed NaN NaN NaN NaN NaNe 0.119209 -1.044236 -0.861849 bar Truef -2.104569 -0.494929 1.071804 bar Falseg NaN NaN NaN NaN NaNh 0.721555 -0.706771 -1.039575 bar True数据缺失,就会产生很多NaN。 ...

June 24, 2021 · 5 min · jiezi

关于pandas:Pandas高级教程之处理text数据

简介在1.0之前,只有一种模式来存储text数据,那就是object。在1.0之后,增加了一个新的数据类型叫做StringDtype 。明天将会给大家解说Pandas中text中的那些事。 创立text的DF先看下常见的应用text来构建DF的例子: In [1]: pd.Series(['a', 'b', 'c'])Out[1]: 0 a1 b2 cdtype: object如果要应用新的StringDtype,能够这样: In [2]: pd.Series(['a', 'b', 'c'], dtype="string")Out[2]: 0 a1 b2 cdtype: stringIn [3]: pd.Series(['a', 'b', 'c'], dtype=pd.StringDtype())Out[3]: 0 a1 b2 cdtype: string或者应用astype进行转换: In [4]: s = pd.Series(['a', 'b', 'c'])In [5]: sOut[5]: 0 a1 b2 cdtype: objectIn [6]: s.astype("string")Out[6]: 0 a1 b2 cdtype: stringString 的办法String能够转换成大写,小写和统计它的长度: In [24]: s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'], ....: dtype="string") ....: In [25]: s.str.lower()Out[25]: 0 a1 b2 c3 aaba4 baca5 <NA>6 caba7 dog8 catdtype: stringIn [26]: s.str.upper()Out[26]: 0 A1 B2 C3 AABA4 BACA5 <NA>6 CABA7 DOG8 CATdtype: stringIn [27]: s.str.len()Out[27]: 0 11 12 13 44 45 <NA>6 47 38 3dtype: Int64还能够进行trip操作: ...

June 23, 2021 · 4 min · jiezi

关于pandas:Pandas高级教程之Dataframe的重排和旋转

简介应用Pandas的pivot办法能够将DF进行旋转变换,本文将会具体解说pivot的机密。 应用Pivotpivot用来重组DF,应用指定的index,columns和values来对现有的DF进行重构。 看一个Pivot的例子: 通过pivot变动,新的DF应用foo中的值作为index,应用bar的值作为columns,zoo作为对应的value。 再看一个工夫变动的例子: In [1]: dfOut[1]: date variable value0 2000-01-03 A 0.4691121 2000-01-04 A -0.2828632 2000-01-05 A -1.5090593 2000-01-03 B -1.1356324 2000-01-04 B 1.2121125 2000-01-05 B -0.1732156 2000-01-03 C 0.1192097 2000-01-04 C -1.0442368 2000-01-05 C -0.8618499 2000-01-03 D -2.10456910 2000-01-04 D -0.49492911 2000-01-05 D 1.071804In [3]: df.pivot(index='date', columns='variable', values='value')Out[3]: variable A B C Ddate 2000-01-03 0.469112 -1.135632 0.119209 -2.1045692000-01-04 -0.282863 1.212112 -1.044236 -0.4949292000-01-05 -1.509059 -0.173215 -0.861849 1.071804如果残余的value,多于一列的话,每一列都会有相应的columns值: In [4]: df['value2'] = df['value'] * 2In [5]: pivoted = df.pivot(index='date', columns='variable')In [6]: pivotedOut[6]: value value2 variable A B C D A B C Ddate 2000-01-03 0.469112 -1.135632 0.119209 -2.104569 0.938225 -2.271265 0.238417 -4.2091382000-01-04 -0.282863 1.212112 -1.044236 -0.494929 -0.565727 2.424224 -2.088472 -0.9898592000-01-05 -1.509059 -0.173215 -0.861849 1.071804 -3.018117 -0.346429 -1.723698 2.143608通过抉择value2,能够失去相应的子集: ...

June 15, 2021 · 6 min · jiezi

关于pandas:Pandas高级教程之Dataframe的合并

简介Pandas提供了很多合并Series和Dataframe的弱小的性能,通过这些性能能够不便的进行数据分析。本文将会具体解说如何应用Pandas来合并Series和Dataframe。 应用concatconcat是最罕用的合并DF的办法,先看下concat的定义: pd.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)看一下咱们常常会用到的几个参数: objs是Series或者Series的序列或者映射。 axis指定连贯的轴。 join : {‘inner’, ‘outer’}, 连贯形式,怎么解决其余轴的index,outer示意合并,inner示意交加。 ignore_index: 疏忽本来的index值,应用0,1,… n-1来代替。 copy:是否进行拷贝。 keys:指定最外层的多层次构造的index。 咱们先定义几个DF,而后看一下怎么应用concat把这几个DF连接起来: In [1]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'], ...: 'B': ['B0', 'B1', 'B2', 'B3'], ...: 'C': ['C0', 'C1', 'C2', 'C3'], ...: 'D': ['D0', 'D1', 'D2', 'D3']}, ...: index=[0, 1, 2, 3]) ...: In [2]: df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'], ...: 'B': ['B4', 'B5', 'B6', 'B7'], ...: 'C': ['C4', 'C5', 'C6', 'C7'], ...: 'D': ['D4', 'D5', 'D6', 'D7']}, ...: index=[4, 5, 6, 7]) ...: In [3]: df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'], ...: 'B': ['B8', 'B9', 'B10', 'B11'], ...: 'C': ['C8', 'C9', 'C10', 'C11'], ...: 'D': ['D8', 'D9', 'D10', 'D11']}, ...: index=[8, 9, 10, 11]) ...: In [4]: frames = [df1, df2, df3]In [5]: result = pd.concat(frames)df1,df2,df3定义了同样的列名和不同的index,而后将他们放在frames中形成了一个DF的list,将其作为参数传入concat就能够进行DF的合并。 ...

June 14, 2021 · 5 min · jiezi

关于pandas:Pandas之深入理解Pandas的数据结构

[toc] 简介本文将会解说Pandas中根本的数据类型Series和DataFrame,并具体解说这两种类型的创立,索引等根本行为。 应用Pandas须要援用上面的lib: In [1]: import numpy as npIn [2]: import pandas as pdSeriesSeries是一维带label和index的数组。咱们应用上面的办法来创立一个Series: >>> s = pd.Series(data, index=index)这里的data能够是Python的字典,np的ndarray,或者一个标量。 index是一个横轴label的list。接下来咱们别离来看下怎么创立Series。 从ndarray创立s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])sOut[67]: a -1.300797b -2.044172c -1.170739d -0.445290e 1.208784dtype: float64应用index获取index: s.indexOut[68]: Index(['a', 'b', 'c', 'd', 'e'], dtype='object')从dict创立d = {'b': 1, 'a': 0, 'c': 2}pd.Series(d)Out[70]: a 0b 1c 2dtype: int64从标量创立pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])Out[71]: a 5.0b 5.0c 5.0d 5.0e 5.0dtype: float64Series 和 ndarraySeries和ndarray是很相似的,在Series中应用index数值体现的就像ndarray: s[0]Out[72]: -1.3007972194268396s[:3]Out[73]: a -1.300797b -2.044172c -1.170739dtype: float64s[s > s.median()]Out[74]: d -0.445290e 1.208784dtype: float64s[[4, 3, 1]]Out[75]: e 1.208784d -0.445290b -2.044172dtype: float64Series和dict如果应用label来拜访Series,那么它的体现就和dict很像: ...

June 11, 2021 · 3 min · jiezi

关于pandas:Pandas之Pandas高级教程以铁达尼号真实数据为例

简介明天咱们会解说一下Pandas的高级教程,包含读写文件、选取子集和图形示意等。 读写文件数据处理的一个关键步骤就是读取文件进行剖析,而后将剖析处理结果再次写入文件。 Pandas反对多种文件格式的读取和写入: In [108]: pd.read_ read_clipboard() read_excel() read_fwf() read_hdf() read_json read_parquet read_sas read_sql_query read_stata read_csv read_feather() read_gbq() read_html read_msgpack read_pickle read_sql read_sql_table read_table 接下来咱们会以Pandas官网提供的Titanic.csv为例来解说Pandas的应用。 Titanic.csv提供了800多个泰坦利特号上乘客的信息,是一个891 rows x 12 columns的矩阵。 咱们应用Pandas来读取这个csv: In [5]: titanic=pd.read_csv("titanic.csv")read_csv办法会将csv文件转换成为pandas 的DataFrame。 默认状况下咱们间接应用DF变量,会默认展现前5行和后5行数据: In [3]: titanicOut[3]: PassengerId Survived Pclass Name Sex ... Parch Ticket Fare Cabin Embarked0 1 0 3 Braund, Mr. Owen Harris male ... 0 A/5 21171 7.2500 NaN S1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female ... 0 PC 17599 71.2833 C85 C2 3 1 3 Heikkinen, Miss. Laina female ... 0 STON/O2. 3101282 7.9250 NaN S3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female ... 0 113803 53.1000 C123 S4 5 0 3 Allen, Mr. William Henry male ... 0 373450 8.0500 NaN S.. ... ... ... ... ... ... ... ... ... ... ...886 887 0 2 Montvila, Rev. Juozas male ... 0 211536 13.0000 NaN S887 888 1 1 Graham, Miss. Margaret Edith female ... 0 112053 30.0000 B42 S888 889 0 3 Johnston, Miss. Catherine Helen "Carrie" female ... 2 W./C. 6607 23.4500 NaN S889 890 1 1 Behr, Mr. Karl Howell male ... 0 111369 30.0000 C148 C890 891 0 3 Dooley, Mr. Patrick male ... 0 370376 7.7500 NaN Q[891 rows x 12 columns]能够应用head(n)和tail(n)来指定特定的行数: ...

June 7, 2021 · 6 min · jiezi

关于pandas:Pandas之Pandas简洁教程

简介pandas是建设在Python编程语言之上的一种疾速,弱小,灵便且易于应用的开源数据分析和解决工具,它含有使数据荡涤和剖析⼯ 作变得更快更简略的数据结构和操作⼯具。pandas常常和其它⼯具⼀同使⽤,如数值计算⼯具NumPy和SciPy,剖析库statsmodels和scikit-learn,和数据可视化库matplotlib等。 pandas是基于NumPy数组构建的,尽管pandas采⽤了⼤量的NumPy编码⻛格,但⼆者最⼤的不同是pandas是专⻔为解决表格和混淆数据设计的。⽽NumPy更适宜解决统⼀的数值数组数据。 本文是对于Pandas的简洁教程。 对象创立因为Pandas是基于NumPy数组来构建的,所以咱们在援用的时候须要同时援用Pandas和NumPy: In [1]: import numpy as npIn [2]: import pandas as pdPandas中最次要的两个数据结构是Series和DataFrame。 Series和一维数组很类似,它是由NumPy的各种数据类型来组成的,同时还蕴含了和这组数据相干的index。 咱们来看一个Series的例子: In [3]: pd.Series([1, 3, 5, 6, 8])Out[3]:0 11 32 53 64 8dtype: int64右边的是索引,左边的是值。因为咱们在创立Series的时候并没有指定index,所以index是从0开始到n-1完结。 Series在创立的时候还能够传入np.nan示意空值: In [4]: pd.Series([1, 3, 5, np.nan, 6, 8])Out[4]:0 1.01 3.02 5.03 NaN4 6.05 8.0dtype: float64DataFrame是⼀个表格型的数据结构,它含有⼀组有序的列,每列能够是不同的值类型(数值、字符串、布尔值等)。 DataFrame既有⾏索引也有列索引,它能够被看做由Series组成的字典(共⽤同⼀个索引)。 看一个创立DataFrame的例子: In [5]: dates = pd.date_range('20201201', periods=6)In [6]: datesOut[6]:DatetimeIndex(['2020-12-01', '2020-12-02', '2020-12-03', '2020-12-04', '2020-12-05', '2020-12-06'], dtype='datetime64[ns]', freq='D')下面咱们创立了一个index的list。 而后应用这个index来创立一个DataFrame: In [7]: pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))Out[7]: A B C D2020-12-01 1.536312 -0.318095 -0.737956 0.1433522020-12-02 1.325221 0.065641 -2.763370 -0.1305112020-12-03 -1.143560 -0.805807 0.174722 0.4270272020-12-04 -0.724206 0.050155 -0.648675 -0.6451662020-12-05 0.182411 0.956385 0.349465 -0.4840402020-12-06 1.857108 1.245928 -0.767316 -1.890586下面的DataFrame接管三个参数,第一个参数是DataFrame的表格数据,第二个参数是index的值,也能够看做是行名,第三个参数是列名。 ...

June 5, 2021 · 6 min · jiezi

关于pandas:pandas数据分析-pandasDataFrame数据修改索引设置数据组合

微信公众号:Python 集中营简略的事件反复做,反复的事件保持做,保持的事件用心做;你的必定是我保持的能源,如果这篇文章对你有帮忙,点个关注吧! 相干扩大库1# -*- coding: UTF-8 -*-23import pandas as pd456data_dict = {'first_col': [1, 2, 3, 4], 'second_col': [5, 6, 7, 8]}78df = pd.DataFrame(data_dict)数据批改 1import numpy as np 2 3# 转换某一列的数据类型 4 5df['first_col']=pd.DataFrame(df['first_col'],dtype=np.float32) 6 7# 从新定义列名 8 9df.columns = ['first_col_1','second_col_1']1011print(df)1213# 批改局部列名1415df.rename(columns = {'first_col_1':'first_col_2','second_col_1':'second_col_2'},inplace = True)1617print(df)1819# 依照某个或多个字段排序,ascending = False为降序、ascending = True为升序2021df = df.sort_values(by=['first_col_2','second_col_2'],ascending = False)2223print(df)2425# 依照索引排序,ascending = False为降序、ascending = True为升序2627df = df.sort_index(axis = 0,ascending = True)2829print(df)3031# 按数据地位批改数据,如下将第二行、第二列数据批改为93233df.iloc[1,1] = 93435print(df)3637# 现有列计算生成新的列3839df['third_col_2'] = df['first_col_2'] + df['second_col_2']4041# first_col_2 second_col_2 third_col_242# 0 1.0 5 6.043# 1 2.0 9 11.044# 2 3.0 7 10.045# 3 4.0 8 12.0索引设置 1# 从新设置索引 2 3df['index']=range(len(df['first_col'])) 4 5df.set_index(df['index']) 6 7print(df) 8 9# 设置日期为索引,定义日期范畴:start开始日期、periods数据行数1011date = pd.date_range(start='1/1/2021',periods=len(df['first_col']))1213df = df.set_index(date)1415print(df)数据连贯与组合 1# 定义两个DataFrame数据 2 3df1 = pd.DataFrame(data_dict) 4 5df2 = pd.DataFrame(data_dict) 6 7# concat() 函数连贯,axis=0示意当两个数据对象连接时存在不同的列不会生成新的列,axis=1示意会生成新的列 8 9df3=pd.concat([df1,df2],axis=0)1011print(df3)1213# 扩大函数append() 向df1中增加df2中的所有行、最初赋值给df31415df3 = df1.append(df2.loc[:])1617print(df3)DataFrame输入 1# excel保留 2 3df.to_excel('/usr/data.xls') 4 5# csv 保留 6 7df.to_csv('/usr/data.csv') 8 9# 输入字典模式1011dict_ = df.to_dict(orient="dict")1213print(dict_)更多精彩返回微信公众号【Python 集中营】,专一于 python 技术栈,材料获取、交换社区、干货分享,期待你的退出~ ...

April 19, 2021 · 1 min · jiezi

关于数据分析:python数据分析-pandasDataFrame基本聚合函数统计数据

相干扩大库1# -*- coding: UTF-8 -*-23import pandas as pd45data_dict = {'first_col': [1, 2, 3, 4], 'second_col': [5, 6, 7, 8]}67df = pd.DataFrame(data_dict)统计简略信息 1# 生成简要的数据统计数据 2 3describe(percentiles=None, include=None, exclude=None) 4# first_col second_col 5# count 4.000000 4.000000 总数量 6# mean 2.500000 6.500000 均值 7# std 1.290994 1.290994 方差 8# min 1.000000 5.000000 最小值 9# 25% 1.750000 5.750000 25%数据量时的数据10# 50% 2.500000 6.500000 50%数据量时的数据11# 75% 3.250000 7.250000 75%数据量时的数据12# max 4.000000 8.000000 最大值1314# percentiles 指定统计量,默认是25%、50%、75%时的数据量15# include 蕴含数据类型,include='all'同时蕴含离散型与数值型的统计特色、include='O'蕴含离散型、默认include=None蕴含数值型16# exclude 不蕴含数据类型,exclude='O'不蕴含离散型1718print(df.describe(percentiles=[.2,.4,.6,.8], include=None, exclude='O'))head()与tail()函数1# head() 函数前多少行23print(df.head(2))45# tail() 函数后多少行67print(df.tail(2))数据聚合统计 1# 获取某一列的和 2 3print(df['first_col'].sum()) 4 5# 获取某一列的均值 6 7print(df['first_col'].mean()) 8 9# 获取某一列的总数量1011print(df['first_col'].count())1213# 获取某一列的最大值1415print(df['first_col'].max())1617# 获取某一列的最小值1819print(df['first_col'].min())数据结构统计 1# 返回列的数据类型 2 3print(df.dtypes) 4 5# size()返回数据总数 6 7print(df.size) 8 9# 返回数据形态,几行几列1011print(df.shape)1213# 返回列数1415print(df.ndim)1617# 返回每一列的名称1819print(df.axes)更多精彩返回微信公众号【Python 集中营】,专一于 python 技术栈,材料获取、交换社区、干货分享,期待你的退出~ ...

April 18, 2021 · 1 min · jiezi

关于pandas:python-dataframe-保留每一列都大于-3-的每一行

Example:保留每一列都大于 3 的每一行。 输出: data: A B C 1 2 3 1 4 5 7 8 9脚本: import pandas as pddf = pd.read_csv('data', header = 0, sep = '\t')df = df[(df > 3).any(1)]后果: A B C1 4 57 8 9

December 17, 2020 · 1 min · jiezi

关于pandas:骚操作嵌套-JSON-秒变-Dataframe

首发于公众号:Python数据迷信作者:东哥腾飞 调用API和文档数据库会返回嵌套的JSON对象,当咱们应用Python尝试将嵌套构造中的键转换为列时,数据加载到pandas中往往会失去如下后果: df = pd.DataFrame.from_records(results [“ issues”],columns = [“ key”,“ fields”])阐明:这里results是一个大的字典,issues是results其中的一个键,issues的值为一个嵌套JSON对象字典的列表,前面会看到JSON嵌套构造。问题在于API返回了嵌套的JSON构造,而咱们关怀的键在对象中确处于不同级别。 嵌套的JSON构造张成这样的。 而咱们想要的是上面这样的。 上面以一个API返回的数据为例,API通常蕴含无关字段的元数据。假如上面这些是咱们想要的字段。 key:JSON密钥,在第一级的地位。summary:第二级的“字段”对象。status name:第三级地位。statusCategory name:位于第4个嵌套级别。如上,咱们抉择要提取的字段在issues列表内的JSON构造中别离处于4个不同的嵌套级别,一环扣一环。 { "expand": "schema,names", "issues": [ { "fields": { "issuetype": { "avatarId": 10300, "description": "", "id": "10005", "name": "New Feature", "subtask": False }, "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "id": "5", "name": "Resolved", "statusCategory": { "colorName": "green", "id": 3, "key": "done", "name": "Done", } }, "summary": "Recovered data collection Defraglar $MFT problem" }, "id": "11861", "key": "CAE-160", }, { "fields": { ... more issues], "maxResults": 5, "startAt": 0, "total": 160}一个不太好的解决方案一种抉择是间接撸码,写一个查找特定字段的函数,但问题是必须对每个嵌套字段调用此函数,而后再调用.apply到DataFrame中的新列。 ...

November 9, 2020 · 1 min · jiezi

关于pandas:再见可视化你好Pandas

起源:Python数据迷信作者:东哥腾飞用Python做数据分析离不开pandas,pnadas更多的承载着解决和变换数据的角色,pands中也内置了可视化的操作,但成果很糙。 因而,大家在用Python做数据分析时,失常的做法是用先pandas先进行数据处理,而后再用Matplotlib、Seaborn、Plotly、Bokeh等对dataframe或者series进行可视化操作。 然而说实话,每个可视化包都有本人独特的办法和函数,常常忘,这是让我始终很头疼的中央。 好消息来了!从最新的pandas版本0.25.3开始,不再须要下面的操作了,数据处理和可视化齐全能够用pandas一个就全副搞定。 pandas当初能够应用Plotly、Bokeh作为可视化的backend,间接实现交互性操作,无需再独自应用可视化包了。 上面咱们一起看看如何应用。 1. 激活backend在import了pandas之后,间接应用上面这段代码激活backend,比方上面要激活plotly。 pd.options.plotting.backend = 'plotly'目前,pandas的backend反对以下几个可视化包。 PlotlyHoloviewsMatplotlibPandas_bokehHyplot2. Plotly backendPlotly的益处是,它基于Javascript版本的库写进去的,因而生成的Web可视化图表,能够显示为HTML文件或嵌入基于Python的Web应用程序中。 上面看下如何用plotly作为pandas的backend进行可视化。 如果还没装置Plotly,则须要装置它pip intsall plotly。如果是在Jupyterlab中应用Plotly,那还须要执行几个额定的装置步骤来显示可视化成果。 首先,装置IPywidgets。 pip install jupyterlab "ipywidgets>=7.5"而后运行此命令以装置Plotly扩大。 jupyter labextension install jupyterlab-plotly@4.8.1示例选自openml.org的的数据集,链接如下: 数据链接:https://www.openml.org/d/187这个数据也是Scikit-learn中的样本数据,所以也能够应用以下代码将其间接导入。 import pandas as pdimport numpy as npfrom sklearn.datasets import fetch_openmlpd.options.plotting.backend = 'plotly'X,y = fetch_openml("wine", version=1, as_frame=True, return_X_y=True)data = pd.concat([X,y], axis=1)data.head()该数据集是葡萄酒相干的,蕴含葡萄酒类型的许多性能和相应的标签。数据集的前几行如下所示。 上面应用Plotly backend摸索一下数据集。 绘图形式与失常应用Pandas内置的绘图操作简直雷同,只是当初以丰盛的Plotly显示可视化成果。 上面的代码绘制了数据集中两个因素之间的关系。 fig = data[['Alcohol', 'Proline']].plot.scatter(y='Alcohol', x='Proline')fig.show() 如果将鼠标悬停在图表上,能够抉择将图表下载为高质量的图像文件。 咱们能够联合Pandas的groupby函数创立一个条形图,总结各类之间Hue的均值差别。 data[['Hue','class']].groupby(['class']).mean().plot.bar() 将class增加到咱们方才创立的散点图中。通过Plotly能够轻松地为每个类利用不同的色彩,以便直观地看到分类。 fig = data[['Hue', 'Proline', 'class']].plot.scatter(x='Hue', y='Proline', color='class', title='Proline and Hue by wine class')fig.show() ...

October 16, 2020 · 1 min · jiezi

关于pandas:Pandas入门教程四

groupby分组import pandas as pdimport numpy as npdf=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)})print(df)grouped=df.groupby('A')print('-'*30)print(grouped.count())print('-'*30)grouped=df.groupby(['A','B'])print(grouped.count())print('-'*30)# 通过函数分组def get_letter_type(letter): if letter.lower() in 'aeiou': return 'a' else: return 'b'grouped=df.groupby(get_letter_type,axis=1)print(grouped.count()) A B C D0 foo one 1.429387 0.6435691 bar one -0.858448 -0.2130342 foo two 0.375644 0.2145843 bar three 0.042284 -0.3304814 foo two -1.421967 0.7681765 bar two 1.293483 -0.3990036 foo one -1.101385 -0.2363417 foo three -0.852603 -1.718694------------------------------ B C DA bar 3 3 3foo 5 5 5------------------------------ C DA B bar one 1 1 three 1 1 two 1 1foo one 2 2 three 1 1 two 2 2------------------------------ a b0 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 3se=pd.Series([1,2,3,4,5],[6,9,8,9,8])print(se)se.groupby(level=0)6 19 28 39 48 5dtype: int64<pandas.core.groupby.generic.SeriesGroupBy object at 0x111b00040># 分组求和grouped=se.groupby(level=0).sum()print(grouped)6 18 89 6dtype: int64df2=pd.DataFrame({'X':['A','B','A','B'],'Y':[1,2,3,4]})print(df2) X Y0 A 11 B 22 A 33 B 4# 按X分组,并查问A列的数据grp=df2.groupby('X').get_group('A')print(grp) X Y0 A 12 A 3Pandas 多级索引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'])print(index)MultiIndex([('bar', 'one'), ('bar', 'two'), ('baz', 'one'), ('baz', 'two'), ('foo', 'one'), ('foo', 'two'), ('qux', 'one'), ('qux', 'two')], names=['first', 'second'])s=pd.Series(np.random.randn(8),index=index)print(s)first secondbar one 0.120979 two -0.440384baz one 0.515106 two -0.019882foo one 1.149595 two -0.369984qux one -0.930438 two 0.146044dtype: float64# 分组求和grouped=s.groupby(level='first')print(grouped.sum())firstbar -0.319405baz 0.495224foo 0.779611qux -0.784394dtype: float64grouped=df.groupby(['A','B'])print(grouped.size())A B bar one 1 three 1 two 1foo one 2 three 1 two 2dtype: int64print(df) A B C D0 foo one 1.429387 0.6435691 bar one -0.858448 -0.2130342 foo two 0.375644 0.2145843 bar three 0.042284 -0.3304814 foo two -1.421967 0.7681765 bar two 1.293483 -0.3990036 foo one -1.101385 -0.2363417 foo three -0.852603 -1.718694print(grouped.describe().head()) C \ count mean std min 25% 50% 75% A B bar one 1.0 -0.858448 NaN -0.858448 -0.858448 -0.858448 -0.858448 three 1.0 0.042284 NaN 0.042284 0.042284 0.042284 0.042284 two 1.0 1.293483 NaN 1.293483 1.293483 1.293483 1.293483 foo one 2.0 0.164001 1.789526 -1.101385 -0.468692 0.164001 0.796694 three 1.0 -0.852603 NaN -0.852603 -0.852603 -0.852603 -0.852603 D \ max count mean std min 25% 50% A B bar one -0.858448 1.0 -0.213034 NaN -0.213034 -0.213034 -0.213034 three 0.042284 1.0 -0.330481 NaN -0.330481 -0.330481 -0.330481 two 1.293483 1.0 -0.399003 NaN -0.399003 -0.399003 -0.399003 foo one 1.429387 2.0 0.203614 0.622191 -0.236341 -0.016364 0.203614 three -0.852603 1.0 -1.718694 NaN -1.718694 -1.718694 -1.718694 ...

September 28, 2020 · 4 min · jiezi

关于pandas:Pandas入门教程二

merge合并DataFrameimport pandas as pdleft=pd.DataFrame({ 'key':['k0','k1','k2','k3','k4','k5'], 'A':['A0','A1','A2','A3','A4','A5'], 'B':['B0','B1','B2','B3','B4','B5']})right=pd.DataFrame({ 'key':['k0','k1','k2','k3','k4','k5'], 'C':['C0','C1','C2','C3','C4','C5'], 'D':['D0','D1','D2','D3','D4','D5']})print(left)print('-'*20)print(right) key A B0 k0 A0 B01 k1 A1 B12 k2 A2 B23 k3 A3 B34 k4 A4 B45 k5 A5 B5-------------------- key C D0 k0 C0 D01 k1 C1 D12 k2 C2 D23 k3 C3 D34 k4 C4 D45 k5 C5 D5# 合并res=pd.merge(left,right)print(res)print('-'*20)# 指定合并的keyres=pd.merge(left,right,on='key')print(res) key A B C D0 k0 A0 B0 C0 D01 k1 A1 B1 C1 D12 k2 A2 B2 C2 D23 k3 A3 B3 C3 D34 k4 A4 B4 C4 D45 k5 A5 B5 C5 D5-------------------- key A B C D0 k0 A0 B0 C0 D01 k1 A1 B1 C1 D12 k2 A2 B2 C2 D23 k3 A3 B3 C3 D34 k4 A4 B4 C4 D45 k5 A5 B5 C5 D5left = 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']})print(left)print('-'*20)print(right) key1 key2 A B0 K0 K0 A0 B01 K1 K1 A1 B12 K2 K2 A2 B23 K3 K3 A3 B3-------------------- key1 key2 C D0 K0 K0 C0 D01 K1 K1 C1 D12 K2 K2 C2 D23 K3 K4 C3 D3# 默认取交加 how='inner'res=pd.merge(left,right,on=['key1','key2'])print(res) key1 key2 A B C D0 K0 K0 A0 B0 C0 D01 K1 K1 A1 B1 C1 D12 K2 K2 A2 B2 C2 D2# how='outer' 取并集res=pd.merge(left,right,on=['key1','key2'],how='outer')print(res) key1 key2 A B C D0 K0 K0 A0 B0 C0 D01 K1 K1 A1 B1 C1 D12 K2 K2 A2 B2 C2 D23 K3 K3 A3 B3 NaN NaN4 K3 K4 NaN NaN C3 D3# 显示合并数据中数据来自哪个表res=pd.merge(left,right,on=['key1','key2'],how='outer',indicator=True)print(res) key1 key2 A B C D _merge0 K0 K0 A0 B0 C0 D0 both1 K1 K1 A1 B1 C1 D1 both2 K2 K2 A2 B2 C2 D2 both3 K3 K3 A3 B3 NaN NaN left_only4 K3 K4 NaN NaN C3 D3 right_only# 左链接res=pd.merge(left,right,on=['key1','key2'],how='left')print(res)print('-'*30)# 右链接res=pd.merge(left,right,on=['key1','key2'],how='right')print(res) key1 key2 A B C D0 K0 K0 A0 B0 C0 D01 K1 K1 A1 B1 C1 D12 K2 K2 A2 B2 C2 D23 K3 K3 A3 B3 NaN NaN------------------------------ key1 key2 A B C D0 K0 K0 A0 B0 C0 D01 K1 K1 A1 B1 C1 D12 K2 K2 A2 B2 C2 D23 K3 K4 NaN NaN C3 D3join 拼接列,次要用于索引上的合并left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'], 'B': ['B0', 'B1', 'B2', 'B3'], 'key': ['K0', 'K1', 'K0', 'K1']})right = pd.DataFrame({'C': ['C0', 'C1'], 'D': ['D0', 'D1']}, index=['K0', 'K1'])print(left)print('-'*15)print(right) A B key0 A0 B0 K01 A1 B1 K12 A2 B2 K03 A3 B3 K1--------------- C DK0 C0 D0K1 C1 D1res=left.join(right,on='key')print(res) A B key C D0 A0 B0 K0 C0 D01 A1 B1 K1 C1 D12 A2 B2 K0 C0 D03 A3 B3 K1 C1 D1Pandas数据透视表df = pd.DataFrame({'Month': ["January", "January", "January", "January", "February", "February", "February", "February", "March", "March", "March", "March"], 'Category': ["Transportation", "Grocery", "Household", "Entertainment", "Transportation", "Grocery", "Household", "Entertainment", "Transportation", "Grocery", "Household", "Entertainment"], 'Amount': [74., 235., 175., 100., 115., 240., 225., 125., 90., 260., 200., 120.]})print(df) Month Category Amount0 January Transportation 74.01 January Grocery 235.02 January Household 175.03 January Entertainment 100.04 February Transportation 115.05 February Grocery 240.06 February Household 225.07 February Entertainment 125.08 March Transportation 90.09 March Grocery 260.010 March Household 200.011 March Entertainment 120.0# 结构一个索引为Category 列为Month 值为Amount的表res=df.pivot(index='Category',columns='Month',values='Amount')print(res)Month February January MarchCategory Entertainment 125.0 100.0 120.0Grocery 240.0 235.0 260.0Household 225.0 175.0 200.0Transportation 115.0 74.0 90.0# 按列求和res.sum(axis=0)MonthFebruary 705.0January 584.0March 670.0dtype: float64# 按行求和res.sum(axis=1)CategoryEntertainment 345.0Grocery 735.0Household 600.0Transportation 279.0dtype: float64pivot_tabledf=pd.read_csv('./pandas/data/titanic.csv')df.columnsIndex(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'], dtype='object')#默认求平均值res=df.pivot_table(index='Sex',columns='Pclass',values='Fare')print(res)Pclass 1 2 3Sex female 106.125798 21.970121 16.118810male 67.226127 19.741782 12.661633# 求最大值res=df.pivot_table(index='Sex',columns='Pclass',values='Fare',aggfunc='max')print(res)Pclass 1 2 3Sex female 512.3292 65.0 69.55male 512.3292 73.5 69.55# 统计个数res=df.pivot_table(index='Sex',columns='Pclass',values='Fare',aggfunc='count')print(res)print('-'*20)# crosstab 统计个数res=pd.crosstab(index=df['Sex'],columns=df['Pclass'])print(res)Pclass 1 2 3Sex female 94 76 144male 122 108 347--------------------Pclass 1 2 3Sex female 94 76 144male 122 108 347# 求平均值res=df.pivot_table(index='Sex',columns='Pclass',values='Fare',aggfunc='mean')print(res)Pclass 1 2 3Sex female 106.125798 21.970121 16.118810male 67.226127 19.741782 12.661633# 计算未成年男女存活率df['minor']=df['Age']<=18res=df.pivot_table(index='minor',columns='Sex',values='Survived',aggfunc='mean')print(res)Sex female maleminor False 0.760163 0.167984True 0.676471 0.338028 ...

September 26, 2020 · 3 min · jiezi

关于pandas:利用-Python-进行数据分析Python-数据分析-第-2-版

译者:SeanCheney欢送任何人参加和欠缺:一个人能够走的很快,然而一群人却能够走的更远。 ApacheCN 机器学习交换群 629470233ApacheCN 学习资源Sklearn 与 TensorFlow 机器学习实用指南<!--split--> 在线浏览PDF格局EPUB格局MOBI格局代码仓库下载本书代码(本书GitHub地址):https://github.com/wesm/pydata-book (倡议把代码下载下来之后,装置好Anaconda 3.6,在目录文件夹中用Jupyter notebook关上) 本书是2017年10月20号正式出版的,和第1版的不同之处有: 包含Python教程内的所有代码降级为Python 3.6(第1版应用的是Python 2.7)更新了Anaconda和其它包的Python装置办法更新了Pandas为2017最新版新增了一章,对于更高级的Pandas工具,外加一些tips简要介绍了应用StatsModels和scikit-learn对有些内容进行了从新排版。(译者注1:最大的扭转是把第1版附录中的Python教程,单列成了当初的第2章和第3章,并且进行了裁减。能够说,本书第2版对老手更为敌对了!) (译者注2:毫无疑问,本书是学习Python数据分析最好的参考书。原本想把书名间接译为《Python数据分析》,这样更简短。然而为了尊重第1版的翻译,思考到继承性,还是用老书名。这样读过第一版的老读者能够不便的用之前的书名检索到第二版。作者在写第二版的时候,有些文字是照搬第一版的。所以第二版的翻译也借鉴copy了第一版翻译:即,如果第二版中有和第一版雷同的文字,则copy第一版的中文译本,感觉不妥的中央会稍加批改,剩下的不同的内容就本人翻译。这样做也是为读过第一版的老读者思考——雷同的内容能够间接跳过。)

August 29, 2020 · 1 min · jiezi

关于pandas:ApacheCN-Pandas-译文集

Pandas 秘籍 零、前言一、Pandas 根底二、数据帧基本操作三、开始数据分析四、抉择数据子集五、布尔索引六、索引对齐七、分组以进行汇总,过滤和转换八、将数据重组为参差的表格九、组合 Pandas 对象十、工夫序列剖析十一、Pandas,Matplotlib 和 Seaborn 的可视化Pandas 学习手册中文第二版 零、前言一、Pandas 与数据分析二、启动和运行 Pandas三、用序列示意单变量数据四、用数据帧示意表格和多元数据五、数据帧的构造操作六、索引数据七、类别数据八、数值统计办法九、存取数据十、整顿数据十一、合并,连贯和重塑数据十二、数据聚合十三、工夫序列建模十四、可视化十五、历史股价剖析精通 Pandas 零、前言一、Pandas 和数据分析简介二、Pandas 装置和支持软件三、Pandas 数据结构四、Pandas 的操作,第一局部 -- 索引和抉择五、Pandas 的操作,第二局部 -- 数据的分组,合并和重塑六、解决缺失数据,工夫序列和 Matplotlib 绘图七、统计之旅 -- 经典办法八、贝叶斯统计简介九、Pandas 库体系结构十、R 与 Pandas 的比拟十一、机器学习简介NumPy 和 Pandas 数据分析实用指南 零、前言一、配置 Python 数据分析环境二、摸索 NumPy三、NumPy 数组上的运算四、Pandas 很乏味! 什么是 Pandas?五、Pandas 的算术,函数利用以及映射六、排序,索引和绘图精通 Pandas 探索性剖析 零、前言一、解决不同品种的数据集二、数据抉择三、解决,转换和重塑数据四、像专业人士一样可视化数据

July 18, 2020 · 1 min · jiezi

关于pandas:精通-Pandas-翻译完成

协定:CC BY-NC-SA 4.0欢送任何人参加和欠缺:一个人能够走的很快,然而一群人却能够走的更远。 在线浏览ApacheCN 面试求职交换群 724187166ApacheCN 学习资源目录精通 Pandas零、前言一、Pandas 和数据分析简介二、Pandas 装置和支持软件三、Pandas 数据结构四、Pandas 的操作,第一局部 -- 索引和抉择五、Pandas 的操作,第二局部 -- 数据的分组,合并和重塑六、解决缺失数据,工夫序列和 Matplotlib 绘图七、统计之旅 -- 经典办法八、贝叶斯统计简介九、Pandas 库体系结构十、R 与 Pandas 的比拟十一、机器学习简介奉献指南本我的项目须要校对,欢送大家提交 Pull Request。 请您怯懦地去翻译和改良翻译。尽管咱们谋求卓越,但咱们并不要求您做到美中不足,因而请不要放心因为翻译上犯错——在大部分状况下,咱们的服务器曾经记录所有的翻译,因而您不用放心会因为您的失误受到无法挽回的毁坏。(改编自维基百科)联系方式负责人飞龙: 562826179其余在咱们的 apachecn/apachecn-ds-zh github 上提 issue.发邮件到 Email: apachecn@163.com.在咱们的 组织学习交换群 中分割群主/管理员即可.资助咱们通过平台自带的打赏性能,或点击这里。

July 18, 2020 · 1 min · jiezi

Pandas-学习手册中文第二版翻译完成

原文:Learning pandas协定:CC BY-NC-SA 4.0 欢送任何人参加和欠缺:一个人能够走的很快,然而一群人却能够走的更远。 在线浏览ApacheCN 面试求职交换群 724187166ApacheCN 学习资源目录Pandas 学习手册中文第二版零、前言一、Pandas 与数据分析二、启动和运行 Pandas三、用序列示意单变量数据四、用数据帧示意表格和多元数据五、数据帧的构造操作六、索引数据七、类别数据八、数值统计办法九、存取数据十、整顿数据十一、合并,连贯和重塑数据十二、数据聚合十三、工夫序列建模十四、可视化十五、历史股价剖析奉献指南本我的项目须要校对,欢送大家提交 Pull Request。 请您怯懦地去翻译和改良翻译。尽管咱们谋求卓越,但咱们并不要求您做到美中不足,因而请不要放心因为翻译上犯错——在大部分状况下,咱们的服务器曾经记录所有的翻译,因而您不用放心会因为您的失误受到无法挽回的毁坏。(改编自维基百科)联系方式负责人飞龙: 562826179其余在咱们的 apachecn/apachecn-ds-zh github 上提 issue.发邮件到 Email: apachecn@163.com.在咱们的 组织学习交换群 中分割群主/管理员即可.资助咱们通过平台自带的打赏性能,或点击这里。

July 16, 2020 · 1 min · jiezi

Pandas-秘籍翻译完成

协定:CC BY-NC-SA 4.0欢送任何人参加和欠缺:一个人能够走的很快,然而一群人却能够走的更远。 在线浏览ApacheCN 面试求职交换群 724187166ApacheCN 学习资源目录Pandas 秘籍零、前言一、Pandas 根底二、数据帧基本操作三、开始数据分析四、抉择数据子集五、布尔索引六、索引对齐七、分组以进行汇总,过滤和转换八、将数据重组为参差的表格九、组合 Pandas 对象十、工夫序列剖析十一、Pandas,Matplotlib 和 Seaborn 的可视化奉献指南本我的项目须要校对,欢送大家提交 Pull Request。 请您怯懦地去翻译和改良翻译。尽管咱们谋求卓越,但咱们并不要求您做到美中不足,因而请不要放心因为翻译上犯错——在大部分状况下,咱们的服务器曾经记录所有的翻译,因而您不用放心会因为您的失误受到无法挽回的毁坏。(改编自维基百科)联系方式负责人飞龙: 562826179其余在咱们的 apachecn/apachecn-ds-zh github 上提 issue.发邮件到 Email: apachecn@163.com.在咱们的 组织学习交换群 中分割群主/管理员即可.资助咱们通过平台自带的打赏性能,或点击这里。

July 13, 2020 · 1 min · jiezi

Pandas-DataFrame-使用总结

Pandas 是一个非常好用的库,总结一下 Pandas DataFrame 常见用法,在使用的时候可以快速找到。Pandas DataFrames 是具有带标签的行和列的二维数据结构,可以存储很多类型的数据。如果你熟悉 Excel 的话,可以将 Pandas DataFrames 看做类似于电子表格。 一、引入import numpy as npimport pandas as pd二、创建data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])c = ['a', 'b', 'c']r = ['A', 'B', 'C']df = pd.DataFrame(data=data, columns=c, index=r)三、排序按列、行名排序# 行名排序 降序df.sort_index(axis=0, ascending=False)# 列名排序 降序df.sort_index(axis=0, ascending=False)按值排序拿出来排序df["a"].sort_values(ascending = False)df 内排序df.sort_values( ['a', 'b', 'c'])四、索引位置索引df.iloc[2] # 选择第二行所有数据, 是Series类型df.iloc[[2]] # 选择第二行所有数据, 是DataFrame类型df.iloc[:, 2] # 选择第二列所有数据, 是Series类型df.iloc[:, [2]] # 选择第二列所有数据, 是DataFrame类型df.iloc[:, 0:2] # 选择0到2列所有数据df.iloc[[2,3], 0:2] # 选择2和3行, 0到2列所有数据df.iat[1, 1] # 根据位置快速取出数据, 获取单个数据推荐这种方法自定义索引df.loc['top'] # 选择指定行数据, 是Series类型df.loc[['top']] # 选择指定行数据, 是DataFrame类型df.loc[:, 'xm'] # 选择指定列数据, 是Series类型(不推荐)df.loc[:, ['xm']] # 选择指定列数据, 是DataFrame类型(不推荐)df.loc[:, ['bj','xm']] # 选择多列数据(不推荐)df.loc[:, 'bj':'xb'] # 选择多列之间所有数据, 列切片只能用这种方法df.loc[['top','count'], 'bj':'xb'] # 选择指定行, 指定列数据df.at['top', 'xm'] # 根据自定义索引快速取出数据, 获取单个数据推荐这种方法布尔索引# 选取所有出生日期大于等于1998年的数据, 这里是字符串比较df[df['csrq']>='1998'] # 选取所有出生日期大于等于1997年小于1999年的数据df[(df['csrq']>='1997')&(data['csrq']<'1999')]# 选取所有出生日期大于等于1997年小于1999年的数据df[df['csrq'].between('1997', '1999')]# 选取所有出生日期大于等于1997年或者姓名为张三的数据df[(df['csrq']>='1997')|(data['xm']=='张三')]# 另一种选取方式(不推荐, 实测效率比上面低)df[df.csrq>='1998'] # 选择字段值为指定内容的数据df[df['xm'].isin(['张三','李四'])] 五、插入与删除# 假设cj列本来不存在, 这样会在列尾添加新的一列cj, 值为s(Series对象), 原地df['cj'] = s # 在第1列位置插入一列dz(地址), 值为s, 原地df.insert(0, 'dz', s)# 在df中添加内容为df2(必须是DataFrame对象)的新列(添加列), 非原地 df.join(df2) # 将df2中的行添加到df的尾部(添加行), 非原地df.append(df2)# 删除单列, 并返回删除的列, 原地df.pop('xm')# 删除指定行, 非原地 df.drop(1) # 删除指定列, axis=1指第2维, axis默认0, 非原地df.drop(['xm', 'xh'], axis=1) 六、DataFrame 重要方法与属性'''重要属性'''df.values # 查看所有元素的valuedf.dtypes # 查看所有元素的类型df.index # 查看所有行名df.index = ['总数', '不同', '最多', '频率'] # 重命名行名df.columns # 查看所有列名df.columns = ['班级', '姓名', '性别', '出生日期'] # 重命名列名df.T # 转置后的df, 非原地'''查看数据'''df.head(n) # 查看df前n条数据, 默认5条df.tail(n) # 查看df后n条数据, 默认5条df.shape() # 查看行数和列数df.info() # 查看索引, 数据类型和内存信息'''数据统计'''df.describe() # 查看数据值列的汇总统计, 是DataFrame类型df.count() # 返回每一列中的非空值的个数df.sum() # 返回每一列的和, 无法计算返回空, 下同df.sum(numeric_only=True) # numeric_only=True代表只计算数字型元素, 下同df.max() # 返回每一列的最大值df.min() # 返回每一列的最小值df.argmax() # 返回最大值所在的自动索引位置df.argmin() # 返回最小值所在的自动索引位置df.idxmax() # 返回最大值所在的自定义索引位置df.idxmin() # 返回最小值所在的自定义索引位置df.mean() # 返回每一列的均值df.median() # 返回每一列的中位数df.var() # 返回每一列的方差df.std() # 返回每一列的标准差df.isnull() # 检查df中空值, NaN为True, 否则False, 返回一个布尔数组df.notnull() # 检查df中空值, 非NaN为True, 否则False, 返回一个布尔数组七、转换成 Numpydf.valuesnp.array(df)八、实战应用获取交易对BTC/USDT最近10日的收盘标准差。 ...

June 1, 2020 · 2 min · jiezi

Python之pandas

dataframe和series操作1、取dataframe数据1) iterrows()for index_, row in df1.iterrows(): print(index_) print(row, row.values[0])iterrows()按行遍历dataframe或series,返回两个元素:行索引和行值,其中行值为Series格式,可以根据list索引取具体的数值。结果: 2) itertuples()itertuples为每一行产生一个namedtuple,并且行的索引值作为元组的第一个元素,pandas类型。 for nametuple in df1.itertuples(): print(nametuple) print(nametuple[0], type(nametuple))3) dataframe按某列的值取数据temp_df[temp_df.c1 == 'aa']['c2']dataframe对象temp_df的c1列值为aa时temp_df的c2列的值; 4) dataframe根据列值取行索引temp_df[temp_df.c1 == 'aa'].index.to_list()temp_df的c1列值为aa时,temp_df的行的索引; 5) dataframe 根据行索引和列名修改dataframe的值final_result.loc[10, 'c1'] = abc将final_result的10行c1列的值改为abc; 6) dataframe根据列名取值sorted(list(set(pre_result['c3'].to_list())))返回list格式,set()去重,list()改回list格式,sorted()排序; 7) 取dataframe的部分列df_after[['c1', 'c3', 'c6']]8) dataframe.loc[0]——根据数字型行索引的值取值,print(retemp.loc[0])retemp: asset_return asset_vol0 1 21 11 12output:asset_return 1asset_vol 29) dataframe.iloc[1]——根据行顺序取值,取第i行,从0开始retemp: asset_returnasset_vol b aee ddoutput:asset_return ddasset_vol ee2、索引1) 修改列名或索引名df_after = df_after.rename(columns={base_type: 'values'})修改列名base_type为’values’。 2) dataframe.set_index('return')——将return列的值作为新的行索引print(retemp, '\n', retemp.set_index('return'))output: return asset_vol0 a b1 dd ee returnasset_vol b aee dd 3) dataframe.reset_index()重置行索引为数字型索引,参数drop=True时丢失原索引列,参数inplace=True时,修改原df,为false时,返回新的df ...

November 3, 2019 · 2 min · jiezi

盘点Pandas-的100个常用函数

作者 | 刘顺祥 来源 | 数据分析1480这一期将分享我认为比较常规的100个实用函数,这些函数大致可以分为六类,分别是统计汇总函数、数据清洗函数、数据筛选、绘图与元素级运算函数、时间序列函数和其他函数。 统计汇总函数数据分析过程中,必然要做一些数据的统计汇总工作,那么对于这一块的数据运算有哪些可用的函数可以帮助到我们呢?具体看如下几张表。 import pandas as pdimport numpy as npx = pd.Series(np.random.normal(2,3,1000))y = 3*x + 10 + pd.Series(np.random.normal(1,2,1000))# 计算x与y的相关系数print(x.corr(y))# 计算y的偏度print(y.skew())# 计算y的统计描述值print(x.describe())z = pd.Series(['A','B','C']).sample(n = 1000, replace = True)# 重新修改z的行索引z.index = range(1000)# 按照z分组,统计y的组内平均值y.groupby(by = z).aggregate(np.mean) # 统计z中个元素的频次print(z.value_counts())a = pd.Series([1,5,10,15,25,30])# 计算a中各元素的累计百分比print(a.cumsum() / a.cumsum()[a.size - 1]) 数据清洗函数同样,数据清洗工作也是必不可少的工作,在如下表格中罗列了常有的数据清洗的函数。 x = pd.Series([10,13,np.nan,17,28,19,33,np.nan,27])#检验序列中是否存在缺失值print(x.hasnans)# 将缺失值填充为平均值print(x.fillna(value = x.mean()))# 前向填充缺失值print(x.ffill()) income = pd.Series(['12500元','8000元','8500元','15000元','9000元'])# 将收入转换为整型print(income.str[:-1].astype(int))gender = pd.Series(['男','女','女','女','男','女'])# 性别因子化处理print(gender.factorize())house = pd.Series(['大宁金茂府 | 3室2厅 | 158.32平米 | 南 | 精装', '昌里花园 | 2室2厅 | 104.73平米 | 南 | 精装', '纺大小区 | 3室1厅 | 68.38平米 | 南 | 简装'])# 取出二手房的面积,并转换为浮点型house.str.split('|').str[2].str.strip().str[:-2].astype(float) ...

October 16, 2019 · 1 min · jiezi

Pandas-数据处理入门教程合集

基础教程Pandas 数据处理(三) - Cheat Sheet 中文版来源,2张图覆盖了几乎所有常用的 Pandas 用法。Pandas_Cheat_Sheet_中文版.pdf 下载Pandas 数据处理(二) - 筛选数据选取列,使用方括号选取行,行标签使用loc,行号使用iloc,ix兼容处理loc与iloc(deprecated)简单的逻辑判断(<, >, ==, &, |, ~ 等)自定义函数,loc,apply,lambdaPandas 数据处理(一) - DataFrame 与 Series创建Series,切片与取值创建DataFrame,获取列与行,修改,删除

July 2, 2019 · 1 min · jiezi

媲美Pandas告诉你Python的Datatable包到底怎么用

作者 | Parul Pandey 【导读】工具包 datatable 的功能特征与 Pandas 非常类似,但更侧重于速度以及对大数据的支持。此外,datatable 还致力于实现更好的用户体验,提供有用的错误提示消息和强大的 API 功能。通过本文的介绍,你将学习到如何在大型数据集中使用 datatable 包进行数据处理,特别在数据量特别大的时候你可以发现它可能比 Pandas 更加强大。 前言data.table 是 R 中一个非常通用和高性能的包,使用简单、方便而且速度快,在 R 语言社区非常受欢迎,每个月的下载量超过 40 万,有近 650 个 CRAN 和 Bioconductor 软件包使用它。如果你是 R 的使用者,可能已经使用过 data.table 包。 而对于 Python 用户,同样存在一个名为 datatable 包,专注于大数据支持、高性能内存/内存不足的数据集以及多线程算法等问题。在某种程度上,datatable 可以被称为是 Python 中的 data.table。 Datatable初教程为了能够更准确地构建模型,现在机器学习应用通常要处理大量的数据并生成多种特征,这已成为必要的。而 Python 的 datatable 模块为解决这个问题提供了良好的支持,以可能的最大速度在单节点机器上进行大数据操作 (最多100GB)。datatable 包的开发由 H2O.ai 赞助,它的第一个用户是 Driverless.ai。 接下来,我们就开始初体验一下 datatable 的简单使用。 安装在 MacOS 系统上,datatable 包可以通过 pip 命令安装,如下图所示: pip install datatable ...

June 27, 2019 · 3 min · jiezi

PyODPS-DataFrame-处理笛卡尔积的几种方式

PyODPS 提供了 DataFrame API 来用类似 pandas 的接口进行大规模数据分析以及预处理,本文主要介绍如何使用 PyODPS 执行笛卡尔积的操作。 笛卡尔积最常出现的场景是两两之间需要比较或者运算。以计算地理位置距离为例,假设大表 Coordinates1 存储目标点经纬度坐标,共有 M 行数据,小表 Coordinates2 存储出发点经纬度坐标,共有 N 行数据,现在需要计算所有离目标点最近的出发点坐标。对于一个目标点来说,我们需要计算所有的出发点到目标点的距离,然后找到最小距离,所以整个中间过程需要产生 M * N 条数据,也就是一个笛卡尔积问题。 haversine 公式首先简单介绍一下背景知识,已知两个地理位置的坐标点的经纬度,求解两点之间的距离可以使用 haversine 公式,使用 Python 的表达如下: def haversine(lat1, lon1, lat2, lon2): # lat1, lon1 为位置 1 的经纬度坐标 # lat2, lon2 为位置 2 的经纬度坐标 import numpy as np dlon = np.radians(lon2 - lon1) dlat = np.radians(lat2 - lat1) a = np.sin( dlat /2 ) **2 + np.cos(np.radians(lat1)) * np.cos(np.radians(lat2)) * np.sin( dlon /2 ) **2 c = 2 * np.arcsin(np.sqrt(a)) r = 6371 # 地球平均半径,单位为公里 return c * rMapJoin目前最推荐的方法就是使用 mapjoin,PyODPS 中使用 mapjoin 的方式十分简单,只需要两个 dataframe join 时指定 mapjoin=True,执行时会对右表做 mapjoin 操作。 ...

June 13, 2019 · 3 min · jiezi

pandas-DataFrame索引行列

pandas DataFrame索引行列python版本: 3.6pandas版本: 0.23.4 行索引索引行有三种方法,分别是 loc iloc ix import pandas as pdimport numpy as npindex = ["a", "b", "c", "d"]data = np.random.randint(10, size=(4, 3))df = pd.DataFrame(data, index=index)""" 0 1 2a 9 7 1b 0 0 7c 2 6 5d 8 2 5"""locloc通过行索引名字来确定行的 单行索引, 返回Series对象df.loc["a"]"""0 91 72 1Name: a, dtype: int64"""df.loc["b"]"""0 01 02 7Name: b, dtype: int64"""多行索引, 返回DataFrame对象df.loc[["a", "c"]]""" 0 1 2a 9 7 1c 2 6 5"""iloc通过行索引序号来确定行的 ...

June 4, 2019 · 2 min · jiezi

Pandas时序数据处理入门

作为一个几乎每天与时间序列数据打交道的人员,我发现panda Python包在时间序列的操作和分析方面有强大优势。 这篇关于panda时间序列数据处理的基本介绍可以带你入门时间序列分析。本文将主要介绍以下操作: 创建一个日期范围处理时间戳数据将字符串数据转换为时间戳在数据框中索引和切片时间序列数据重新采样不同时间段的时间序列汇总/汇总统计数据计算滚动统计数据,如滚动平均值处理丢失数据了解unix/epoch时间的基础知识了解时间序列数据分析的常见陷阱接下来我们一起步入正题。如果想要处理已有的实际数据,你可能考虑从使用panda read_csv将文件读入数据框开始,然而在这里,我们将直接从处理生成的数据开始。 首先导入我们将会使用到的库,然后用它们创建日期范围 import pandas as pdfrom datetime import datetimeimport numpy as npdate_rng = pd.date_range(start='1/1/2018', end='1/08/2018', freq='H')这个日期范围的时间戳为每小时一次。如果我们调用date_rng,我们会看到如下所示: DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 01:00:00', '2018-01-01 02:00:00', '2018-01-01 03:00:00', '2018-01-01 04:00:00', '2018-01-01 05:00:00', '2018-01-01 06:00:00', '2018-01-01 07:00:00', '2018-01-01 08:00:00', '2018-01-01 09:00:00', ... '2018-01-07 15:00:00', '2018-01-07 16:00:00', '2018-01-07 17:00:00', '2018-01-07 18:00:00', '2018-01-07 19:00:00', '2018-01-07 20:00:00', '2018-01-07 21:00:00', '2018-01-07 22:00:00', '2018-01-07 23:00:00', '2018-01-08 00:00:00'], dtype='datetime64[ns]', length=169, freq='H')我们可以检查第一个元素的类型: type(date_rng[0])#returnspandas._libs.tslib.Timestamp让我们用时间戳数据的创建一个示例数据框,并查看前15个元素: df = pd.DataFrame(date_rng, columns=['date'])df['data'] = np.random.randint(0,100,size=(len(date_rng)))df.head(15) ...

May 10, 2019 · 2 min · jiezi

数据科学库pandas笔记3

缺失数据的处理1. 缺失数据的表现对于一些数据,可能某些值是空的,是缺失的。pandas中可以有多种处理缺失数据的方式。在pandas中,缺失数据的表现是NaN(Not a Number),可以使用isnull()函数检测出是否有数据缺失。 In [4]: data = pd.Series(['aaa','bbb',np.nan,'ddd'])In [5]: dataOut[5]:0 aaa1 bbb2 NaN3 ddddtype: objectIn [6]: data.isnull()Out[6]:0 False1 False2 True3 Falsedtype: boolisnull返回一个布尔型的对象,这些布尔值表示哪些值是缺失值NaN,该对象返回的类型和原类型一样。 处理缺失数据的方式有多种,常见为删除缺失数据与填充缺失数据。 2. 丢弃缺失数据pandas的dropna方法可以有效的删除掉缺失数据,对于Series来说,dropna方法返回一个仅含非空数据和索引值的Series: In [7]: dataOut[7]:0 aaa1 bbb2 NaN3 ddddtype: objectIn [8]: data.dropna()Out[8]:0 aaa1 bbb3 ddddtype: object对于DataFrame,dropna可以删除所有含有空值的行或列,也可以根据个人删除指定的行或列,dropna默认会删除所有含有NaN的行: In [17]: dfOut[17]: name age area0 aa 18 北京1 NaN 18 广州2 cc 20 NaNIn [18]: df.dropna()Out[18]: name age area0 aa 18 北京传入how='all',那么dropna只会删除一行全是缺失值的行: In [19]: df.loc[3]=[np.nan,np.nan,np.nan]In [20]: dfOut[20]: name age area0 aa 18.0 北京1 NaN 18.0 广州2 cc 20.0 NaN3 NaN NaN NaNIn [21]: df.dropna(how='all')Out[21]: name age area0 aa 18.0 北京1 NaN 18.0 广州2 cc 20.0 NaN如果要删除有缺失值的一列,只需要传入axis=1: ...

May 2, 2019 · 3 min · jiezi

数据科学库pandas笔记2

对于pandas来说,掌握了Series和DataFrame的基本使用后,pandas还提供了很多高阶的函数与方法可以实现更加高级的功能,使用它们可以提高分析的效率,满足更多的需求。pandas高阶函数与方法依旧以一个简单的DataFrame为例: In [161]: dfOut[161]: city education top avg work_year0 上海 本科 9 8.0 3年1 广州 硕士 15 11.0 2年2 广州 本科 12 10.0 应届毕业生3 北京 本科 13 12.0 2年4 北京 本科 11 8.0 1年下面的函数或者方法操作都是以这个DataFrame对象为例。 1. 转置方法T这个方法可以实现行标签和列标签的转置,常用于矩阵运算方面。 In [161]: dfOut[161]: city education top avg work_year0 上海 本科 9 8.0 3年1 广州 硕士 15 11.0 2年2 广州 本科 12 10.0 应届毕业生3 北京 本科 13 12.0 2年4 北京 本科 11 8.0 1年In [162]: df.TOut[162]: 0 1 2 3 4city 上海 广州 广州 北京 北京education 本科 硕士 本科 本科 本科top 9 15 12 13 11avg 8 11 10 12 8work_year 3年 2年 应届毕业生 2年 1年2. 排序与排名pandas中的排序有两种,一种是对行或者列索引(sort_index)进行排序,另外一种是按值对一列即Series对象(sort_values)进行排序。 ...

May 1, 2019 · 4 min · jiezi

pandas数据结构之DataFrame

DataFrame入门DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。 下面记录DataFrame的常见使用,引入pandas约定: from pandas import Series,DataFrameimport pandas as pdDataFrame基本操作1. 创建一个DataFrame数据框 创建一个DataFrame最常见的方法是传入一个等长的列表或者Numpy数组组成的字典。 In [16]: d = { ...: "name":["cat","dog","lion"], ...: "age":[3,5,6], ...: "sex":["male","female","male"] ...: }In [17]: dOut[17]:{'name': ['cat', 'dog', 'lion'], 'age': [3, 5, 6], 'sex': ['male', 'female', 'male']}In [18]: df = pd.DataFrame(d)In [19]: dfOut[19]: name age sex0 cat 3 male1 dog 5 female2 lion 6 male2. 查看数据框的概述 In [20]: df.info()<class 'pandas.core.frame.DataFrame'>RangeIndex: 3 entries, 0 to 2 # 三个索引,从0到2Data columns (total 3 columns): # 字段信息name 3 non-null object # 字符串类型age 3 non-null int64 # 整型sex 3 non-null object # 字符串类型dtypes: int64(1), object(2) # 统计数据类型信息memory usage: 152.0+ bytes # 占用内存大小3. 切片和索引 ...

April 30, 2019 · 3 min · jiezi

Pandas之旅(七) 谁说pandas慢

Pandas 加速大家好,今天我们来看有关pandas加速的小技巧,不知道大家在刚刚接触pandas的时候有没有听过如下的说法pandas太慢了,运行要等半天**其实我想说的是,慢不是pandas的错,大家要知道pandas本身是在Numpy上建立起来的包,在很多情况下是支持向量化运算的,而且还有C的底层设计,所以我今天主要想从几个方面和大家分享一下pandas加速的小技巧,与往常一样,文章分成四部分,本文结构如下:使用datetime类型来处理和时间序列有关的数据批量计算的技巧通过HDFStore存储数据节省时间源码,相关数据及GitHub地址现在就让我们开始吧1. 使用datetime类型来处理和时间序列有关的数据首先这里我们使用的数据源是一个电力消耗情况的数据(energy_cost.csv),非常贴近生活而且也是和时间息息相关的,用来做测试在合适不过了,这个csv文件大家可以在第四部分找到下载的地方哈import os# 这两行仅仅是切换路径,方便我上传Github,大家不用理会,只要确认csv文件和py文件再一起就行啦os.chdir(“F:\Python教程\segmentfault\pandas_share\Pandas之旅_07 谁说pandas慢”)现在让我们看看数据大概长什么样子import numpy as npimport pandas as pdf"Using {pd.name},{pd.version}"‘Using pandas,0.23.0’df = pd.read_csv(’energy_cost.csv’,sep=’,’)df.head() date_time energy_kwh 0 2001/1/13 0:00 0.586 1 2001/1/13 1:00 0.580 2 2001/1/13 2:00 0.572 3 2001/1/13 3:00 0.596 4 2001/1/13 4:00 0.592 现在我们看到初始数据的样子了,主要有date_time和energy_kwh这两列,来表示时间和消耗的电力,比较好理解,下面让我们来看一下数据类型df.dtypes>>> date_time object energy_kwh float64 dtype: objecttype(df.iat[0,0])>>> str这里有个小问题,Pandas和NumPy有dtypes(数据类型)的概念。如果未指定参数,则date_time这一列的数据类型默认object,所以为了之后运算方便,我们可以把str类型的这一列转化为timestamp类型:df[‘date_time’] = pd.to_datetime(df[‘date_time’])df.dtypes>>> date_time datetime64[ns] energy_kwh float64 dtype: object先在大家可以发现我们通过用pd.to_datetime这个方法已经成功的把date_time这一列转化为了datetime64类型df.head() date_time energy_kwh 0 2001-01-13 00:00:00 0.586 1 2001-01-13 01:00:00 0.580 2 2001-01-13 02:00:00 0.572 3 2001-01-13 03:00:00 0.596 4 2001-01-13 04:00:00 0.592 现在再来看数据, 发现已经和刚才不同了,我们还可以通过指定format参数实现一样的效果,速度上也会快一些%%timeit -n 10def convert_with_format(df, column_name): return pd.to_datetime(df[column_name],format=’%Y/%m/%d %H:%M’)df[‘date_time’]=convert_with_format(df, ‘date_time’)>>>722 µs ± 334 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)有关具体的日期自定义相关方法,大家点击这里查看2. 批量计算的技巧首先,我们假设根据用电的时间段不同,电费价目表如下:Typecents/kwhperiodePeak2817:00 to 24:00Shoulder207:00 to 17:00Off-Peak120:00 to 7:00假设我们想要计算出电费,我们可以先写出一个根据时间动态计算电费的方法“apply_tariff“def apply_tariff(kwh, hour): “““Calculates cost of electricity for given hour.””” if 0 <= hour < 7: rate = 12 elif 7 <= hour < 17: rate = 20 elif 17 <= hour < 24: rate = 28 else: raise ValueError(f’Invalid hour: {hour}’) return rate * kwh好啦,现在我们想要在数据中新增一列 ‘cost_cents’ 来表示总价钱,我们有很多选择,首先能想到的方法便是iterrows(),它可以让我们循环遍历Dataframe的每一行,根据条件计算并赋值给新增的‘cost_cents’列iterrows()首先我们能做的是循环遍历流程,让我们先用.iterrows()替代上面的方法来试试:%%timeit -n 10def apply_tariff_iterrows(df): energy_cost_list = [] for index, row in df.iterrows(): # Get electricity used and hour of day energy_used = row[’energy_kwh’] hour = row[‘date_time’].hour # Append cost list energy_cost = apply_tariff(energy_used, hour) energy_cost_list.append(energy_cost) df[‘cost_cents’] = energy_cost_listapply_tariff_iterrows(df)983 ms ± 65.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)我们为了测试方便,所有的方法都会循环10次来比较耗时,这里很明显我们有很大的改进空间,下面我们用apply方法来优化apply()%%timeit -n 10def apply_tariff_withapply(df): df[‘cost_cents’] = df.apply( lambda row: apply_tariff( kwh=row[’energy_kwh’], hour=row[‘date_time’].hour), axis=1)apply_tariff_withapply(df)247 ms ± 24.3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)这回速度得到了很大的提升,但是显然我们还没有get到pandas加速的精髓:矢量化操作。下面让我们开始提速isin()假设我们现在的电价是定值,不根据用电时间段来改变,那么pandas中最快的方法那就是采用(df[‘cost_cents’] = df[’energy_kwh’] * price),这就是一个简单的矢量化操作示范。它基本是在Pandas中运行最快的方式。目前的问题是我们的价格是动态的,那么如何将条件判断添加到Pandas中的矢量化运算中呢?答案就是我们根据条件选择和分组DataFrame,然后对每个选定的组应用矢量化操作:#先让我们把时间序列作为索引df.set_index(‘date_time’, inplace=True)%%timeit -n 10def apply_tariff_isin(df): # Define hour range Boolean arrays peak_hours = df.index.hour.isin(range(17, 24)) shoulder_hours = df.index.hour.isin(range(7, 17)) off_peak_hours = df.index.hour.isin(range(0, 7)) # Apply tariffs to hour ranges df.loc[peak_hours, ‘cost_cents’] = df.loc[peak_hours, ’energy_kwh’] * 28 df.loc[shoulder_hours,‘cost_cents’] = df.loc[shoulder_hours, ’energy_kwh’] * 20 df.loc[off_peak_hours,‘cost_cents’] = df.loc[off_peak_hours, ’energy_kwh’] * 12apply_tariff_isin(df)5.7 ms ± 871 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)这回我们发现速度是真正起飞了,首先我们根据用电的三个时段把df进行分三组,再依次进行三次矢量化操作,大家可以发现最后减少了很多时间,原理很简单:在运行的时候,.isin()方法返回一个布尔值数组,如下所示:[False, False, False, …, True, True, True]接下来布尔数组传递给DataFrame的.loc索引器时,我们获得一个仅包含与3个用电时段匹配DataFrame切片。然后简单的进行乘法操作就行了,这样做的好处是我们已经不需要刚才提过的apply方法了,因为不在存在遍历所有行的问题我们可以做的更好吗?通过观察可以发现,在apply_tariff_isin()中,我们仍然在通过调用df.loc和df.index.hour.isin()来进行一些“手动工作”。如果想要进一步提速,我们可以使用cut方法%%timeit -n 10def apply_tariff_cut(df): cents_per_kwh = pd.cut(x=df.index.hour, bins=[0, 7, 17, 24], include_lowest=True, labels=[12, 20, 28]).astype(int) df[‘cost_cents’] = cents_per_kwh * df[’energy_kwh’]140 ns ± 29.9 ns per loop (mean ± std. dev. of 7 runs, 10 loops each)效果依然锋利,速度上有了成倍的提升不要忘了用Numpy众所周知,Pandas是在Numpy上建立起来的,所以在Numpy中当然有类似cut的方法可以实现分组,从速度上来讲差不太多%%timeit -n 10def apply_tariff_digitize(df): prices = np.array([12, 20, 28]) bins = np.digitize(df.index.hour.values, bins=[7, 17, 24]) df[‘cost_cents’] = prices[bins] * df[’energy_kwh’].values54.9 ns ± 19.3 ns per loop (mean ± std. dev. of 7 runs, 10 loops each)正常情况下,以上的加速方法是能满足日常需要的,如果有特殊的需求,大家可以上网看看有没有相关的第三方加速包3. 通过HDFStore存储数据节省时间这里主要想强调的是节省预处理的时间,假设我们辛辛苦苦搭建了一些模型,但是每次运行之前都要进行一些预处理,比如类型转换,用时间序列做索引等,如果不用HDFStore的话每次都会花去不少时间,这里Python提供了一种解决方案,可以把经过预处理的数据存储为HDF5格式,方便我们下次运行时直接调用。下面就让我们把本篇文章的df通过HDF5来存储一下:# Create storage object with filename processed_datadata_store = pd.HDFStore(‘processed_data.h5’)# Put DataFrame into the object setting the key as ‘preprocessed_df’data_store[‘preprocessed_df’] = dfdata_store.close()现在我们可以关机下班了,当明天接着上班后,通过key(“preprocessed_df”)就可以直接使用经过预处理的数据了# Access data storedata_store = pd.HDFStore(‘processed_data.h5’)# Retrieve data using keypreprocessed_df = data_store[‘preprocessed_df’]data_store.close()preprocessed_df.head() energy_kwh cost_cents date_time 2001-01-13 00:00:00 0.586 7.032 2001-01-13 01:00:00 0.580 6.960 2001-01-13 02:00:00 0.572 6.864 2001-01-13 03:00:00 0.596 7.152 2001-01-13 04:00:00 0.592 7.104 如上图所示,现在我们可以发现date_time已经是处理为index了4. 源码,相关数据及GitHub地址这一期为大家分享了一些pandas加速的实用技巧,希望可以帮到各位小伙伴,当然,类似的技巧还有很多,但是核心思想应该一直围绕矢量化操作上,毕竟是基于Numpy上建立的包,如果大家有更好的办法,希望可以在我的文章底下留言哈我把这一期的ipynb文件,py文件以及我们用到的energy_cost.csv放到了Github上,大家可以点击下面的链接来下载:Github仓库地址: https://github.com/yaozeliang/pandas_share希望大家能够继续支持我,这一篇文章已经是Pandas系列的最后一篇了,虽然一共只写了7篇文章,但是我认为从实用性上来讲并没有太逊色于收费课程(除了少了很多漂亮的ppt),接下来我会再接再厉,分享一下我对R (ggplot2)或者matplotlib的学习经验!!Pandas之旅到此结束。撒花 ...

April 5, 2019 · 3 min · jiezi

Pandas之旅(六): 字符串实用方法汇总

有关字符串基本方法大家好,我又回来了! 之前的几期我们已经简单了解了pandas的基础操作,但是只要涉及到数据,最常见的就是String(字符串)类型,所以很多时候我们其实都在和字符串打交道,所以今天,我会把我自己总结的,有关字符串的常用方法分享给大家,希望能够帮到各位小伙伴~Split and formatlatitude = ‘37.24N’longitude = ‘-115.81W’‘Coordinates {0},{1}’.format(latitude,longitude)>>> ‘Coordinates 37.24N,-115.81W’f’Coordinates {latitude},{longitude}’>>>‘Coordinates 37.24N,-115.81W’’{0},{1},{2}’.format((‘abc’))>>>‘a,b,c’coord = {“latitude”:latitude,“longitude”:longitude}‘Coordinates {latitude},{longitude}’.format(**coord)>>>‘Coordinates 37.24N,-115.81W’Access argument’ s attributeclass Point: def init(self,x,y): self.x,self.y = x,y def str(self): return ‘Point({self.x},{self.y})’.format(self = self) def repr(self): return f’Point({self.x},{self.y})’test_point = Point(4,2)test_point>>> Point(4,2)str(Point(4,2))>>>‘Point(4,2)‘Replace with %s , %r :" repr() shows the quote {!r}, while str() doesn’t:{!s} “.format(‘a1’,‘a2’)>>> " repr() shows the quote ‘a1’, while str() doesn’t:a2 “Align :’{:<30}’.format(’left aligned’)>>>’left aligned ‘’{:>30}’.format(‘right aligned’)>>>’ right aligned’’{:^30}’.format(‘centerd’)>>>’ centerd ‘’{:^30}’.format(‘centerd’)>>>’centerd*‘Replace with %x , %o :“int:{0:d}, hex:{0:x}, oct:{0:o}, bin:{0:b}".format(42)>>>‘int:42, hex:2a, oct:52, bin:101010’’{:,}’.format(12345677)>>>‘12,345,677’Percentage :points = 19total = 22’Correct answers: {:.2%}’.format(points/total)>>>‘Correct answers: 86.36%‘Date :import datetime as dtf”{dt.datetime.now():%Y-%m-%d}">>>‘2019-03-27’f”{dt.datetime.now():%d_%m_%Y}">>>‘27_03_2019’today = dt.datetime.today().strftime("%d_%m_%Y”)today'27_03_2019’Split without parameters :“this is a test”.split()>>>[’this’, ‘is’, ‘a’, ’test’]Concatenate :‘do’*2>>>‘dodo’orig_string =‘Hello’orig_string+’,World’>>>‘Hello,World’full_sentence = orig_string+’,World’full_sentence>>>‘Hello,World’Check string type , slice,count,strip :strings = [‘do’,’re’,‘mi’]’, ‘.join(strings)>>>‘do, re, mi’‘z’ not in ‘abc’>>> Trueord(‘a’), ord(’#’)>>> (97, 35)chr(97)>>>‘a’s = “foodbar"s[2:5]>>>‘odb’s[:4] + s[4:]>>>‘foodbar’s[:4] + s[4:] == s>>>Truet=s[:]id(s)>>>1547542895336id(t)>>>1547542895336s is t>>>Trues[0:6:2]>>>‘fob’s[5:0:-2]>>>‘ado’s = ’tomorrow is monday’reverse_s = s[::-1]reverse_s>>>‘yadnom si worromot’s.capitalize()>>>‘Tomorrow is monday’s.upper()>>>‘TOMORROW IS MONDAY’s.title()>>>‘Tomorrow Is Monday’s.count(‘o’)>>> 4"foobar”.startswith(‘foo’)>>>True"foobar".endswith(‘ar’)>>>True"foobar".endswith(‘oob’,0,4)>>>True"foobar".endswith(‘oob’,2,4)>>>False"My name is yo, I work at SG".find(‘yo’)>>>11# If can’t find the string, return -1"My name is ya, I work at Gener".find(‘gent’)>>>-1# Check a string if consists of alphanumeric characters"abc123".isalnum()>>>True"abc%123".isalnum()>>>False"abcABC".isalpha()>>>True"abcABC1".isalpha()>>>False'123’.isdigit()>>>True'123abc’.isdigit()>>>False’abc’.islower()>>>True"This Is A Title".istitle()>>>True"This is a title".istitle()>>>False’ABC’.isupper()>>>True’ABC1%’.isupper()>>>True’foo’.center(10)>>>’ foo ’’ foo bar baz ‘.strip()>>>‘foo bar baz’’ foo bar baz ‘.lstrip()>>>‘foo bar baz ’’ foo bar baz ‘.rstrip()>>>’ foo bar baz’“foo abc foo def fo ljk “.replace(‘foo’,‘yao’)>>>‘yao abc yao def fo ljk ‘‘www.realpython.com’.strip(‘w.moc’)>>>‘realpython’‘www.realpython.com’.strip(‘w.com’)>>>‘realpython’‘www.realpython.com’.strip(‘w.ncom’)>>>‘realpyth’Convert to lists :’, ‘.join([‘foo’,‘bar’,‘baz’,‘qux’])>>>‘foo, bar, baz, qux’list(‘corge’)>>>[‘c’, ‘o’, ‘r’, ‘g’, ’e’]’:’.join(‘corge’)>>>‘c⭕r:g:e’‘www.foo’.partition(’.’)>>>(‘www’, ‘.’, ‘foo’)‘foo@@bar@@baz’.partition(’@@’)>>>(‘foo’, ‘@@’, ‘bar@@baz’)‘foo@@bar@@baz’.rpartition(’@@’)>>>(‘foo@@bar’, ‘@@’, ‘baz’)‘foo.bar’.partition(’@@’)>>>(‘foo.bar’, ‘’, ‘’)# By default , rsplit split a string with white space’foo bar adf yao’.rsplit()>>>[‘foo’, ‘bar’, ‘adf’, ‘yao’]‘foo.bar.adf.ert’.split(’.’)>>>[‘foo’, ‘bar’, ‘adf’, ’ert’]‘foo\nbar\nadfa\nlko’.splitlines()>>>[‘foo’, ‘bar’, ‘adfa’, ’lko’]总结除了我以上总结的这些,还有太多非常实用的方法,大家可以根据自己的需求去搜索啦!我把这一期的ipynb文件和py文件放到了Github上,大家如果想要下载可以点击下面的链接:Github仓库地址: https://github.com/yaozeliang/pandas_share希望大家能够继续支持我,完结,撒花 ...

March 28, 2019 · 2 min · jiezi

Pandas读写CSV文件

读csv使用pandas读取import pandas as pdimport csvif name == ‘main’:# header=0——表示csv文件的第一行默认为dataframe数据的行名称,# index_col=0——表示使用第0列作为dataframe的行索引,# squeeze=True——表示如果文件只包含一列,则返回一个序列。file_dataframe = pd.read_csv(’../datasets/data_new_2/csv_file_name.csv’, header=0, index_col=0, squeeze=True)# 结果: # 当参数index_col=False 时,自动生成行索引0到n# csv数据: data_1 = []# 读取行索引一样的数据,保存为listtry: # 行索引为i的数据有多行,列为’pre_star’ data_1.extend(file_dataframe .loc[i][‘pre_star’].values.astype(float))except AttributeError: # 行索引为i的数据只有单行, data_1.extend([file_dataframe .loc[i][‘pre_star’]])# 多行结果 # 行索引为i的数据只有一行时,不能对file_dataframe .loc[i][‘pre_star’]使用.values,否则会报错:写csv使用csv写stu1 = [lid, k, pre_count_data[k]]# 打开文件,写模式为追加’a’out = open(’../results/write_file.csv’, ‘a’, newline=’’)# 设定写入模式csv_write = csv.writer(out, dialect=‘excel’)# 写入具体内容csv_write.writerow(stu1)

March 27, 2019 · 1 min · jiezi

Pandas之旅(四) : 可能是社区内最实用的Pandas技巧

Pandas不为人知的七大实用技巧大家好,我今天勤快地回来了,这一期主要是和大家分享一些pandas的实用技巧,会在日常生活中大大提升效率,希望可以帮助到大家,还是老样子,先给大家奉上这一期的章节目录:自定义pandas选项,设置实用pandas中testing模块构建测试数据巧用accessor访问器合并其他列拼接DatetimeIndex使用分类数据(Categorical Data)节省时间和空间利用Mapping巧妙实现映射压缩pandas对象源码及GitHub地址好啦,话不多说,让我们一个个看吧1. 自定义pandas选项,设置首先,大家可能不知道,pandas里面有一个方法pd.set_option(),利用它我们可以改变一些pandas中默认的核心设置,从而适应我们自身的需要,开始前还是老样子,让我们先导入numpy和pandas包import numpy as npimport pandas as pdf’Using {pd.name}, Version {pd.version}‘‘Using pandas, Version 0.23.0’现在让我们编写一个start方法来实现自定义pandas设置def start(): options = { ‘display’: { ‘max_columns’: None, ‘max_colwidth’: 25, ’expand_frame_repr’: False, # Don’t wrap to multiple pages ‘max_rows’: 14, ‘max_seq_items’: 50, # Max length of printed sequence ‘precision’: 4, ‘show_dimensions’: False }, ‘mode’: { ‘chained_assignment’: None # Controls SettingWithCopyWarning } } for category, option in options.items(): for op, value in option.items(): pd.set_option(f’{category}.{op}’, value) # Python 3.6+if name == ‘main’: start() del start # Clean up namespace in the interpreter大家可以发现,我们在方法的最后调用了pandas的set_option方法,直接利用我们自定义的参数替代了原有的pandas参数,现在让我们测试一下:pd.get_option(‘display.max_rows’)Out:14可以发现max_rows 已经被替换成了我们设置的14,现在用一个真实的例子,我们利用一组公开的鲍鱼各项指标的数据来实验,数据源来自机器学习平台的公开数据url = (‘https://archive.ics.uci.edu/ml/' ‘machine-learning-databases/abalone/abalone.data’)cols = [‘sex’, ’length’, ‘diam’, ‘height’, ‘weight’, ‘rings’]abalone = pd.read_csv(url, usecols=[0, 1, 2, 3, 4, 8], names=cols)abalone sex length diam height weight rings 0 M 0.455 0.365 0.095 0.5140 15 1 M 0.350 0.265 0.090 0.2255 7 2 F 0.530 0.420 0.135 0.6770 9 3 M 0.440 0.365 0.125 0.5160 10 4 I 0.330 0.255 0.080 0.2050 7 5 I 0.425 0.300 0.095 0.3515 8 6 F 0.530 0.415 0.150 0.7775 20 … … … … … … … 4170 M 0.550 0.430 0.130 0.8395 10 4171 M 0.560 0.430 0.155 0.8675 8 4172 F 0.565 0.450 0.165 0.8870 11 4173 M 0.590 0.440 0.135 0.9660 10 4174 M 0.600 0.475 0.205 1.1760 9 4175 F 0.625 0.485 0.150 1.0945 10 4176 M 0.710 0.555 0.195 1.9485 12 我们可以看到,数据截断为14行,保留了小数点后4位小数作为精度,和我们刚刚设置的precision=4是一样的2. 实用pandas中testing模块构建测试数据通过pandas.util.testing提供的方法,我们可以很容易的通过几行代码就构建出一个简单的测试数据类型,比如我们现在构建一个DataTime类型的数据,时间间隔为月:import pandas.util.testing as tmtm.N, tm.K = 15, 3 # 规定行和列import numpy as npnp.random.seed(444)tm.makeTimeDataFrame(freq=‘M’).head() # 设置时间间隔为月# tm.makeTimeDataFrame(freq=‘D’).head() 设置时间间隔为天 A B C 2000-01-31 0.3574 -0.8804 0.2669 2000-02-29 0.3775 0.1526 -0.4803 2000-03-31 1.3823 0.2503 0.3008 2000-04-30 1.1755 0.0785 -0.1791 2000-05-31 -0.9393 -0.9039 1.1837 瞎生成一组乱七八糟的数据:tm.makeDataFrame().head() A B C nTLGGTiRHF -0.6228 0.6459 0.1251 WPBRn9jtsR -0.3187 -0.8091 1.1501 7B3wWfvuDA -1.9872 -1.0795 0.2987 yJ0BTjehH1 0.8802 0.7403 -1.2154 0luaYUYvy1 -0.9320 1.2912 -0.2907 关于可以随机生成的数据类型, 一共大概有30多种,大家如果感兴趣可以多试试:[i for i in dir(tm) if i.startswith(‘make’)][‘makeBoolIndex’, ‘makeCategoricalIndex’, ‘makeCustomDataframe’, ‘makeCustomIndex’, ‘makeDataFrame’, ‘makeDateIndex’, ‘makeFloatIndex’, ‘makeFloatSeries’, ‘makeIntIndex’, ‘makeIntervalIndex’, ‘makeMissingCustomDataframe’, ‘makeMissingDataframe’, ‘makeMixedDataFrame’, ‘makeMultiIndex’, ‘makeObjectSeries’, ‘makePanel’, ‘makePeriodFrame’, ‘makePeriodIndex’, ‘makePeriodPanel’, ‘makePeriodSeries’, ‘makeRangeIndex’, ‘makeStringIndex’, ‘makeStringSeries’, ‘makeTimeDataFrame’, ‘makeTimeSeries’, ‘makeTimedeltaIndex’, ‘makeUIntIndex’, ‘makeUnicodeIndex’]这样我们如果有测试的需求,会很容易地构建相对应的假数据来测试。3. 巧用accessor访问器accessor(访问器) 具体就是类似getter和setter,当然,Python里面不提倡存在setter和getter方法,但是这样可以便于大家理解,pandas Series类型有3类accessor:pd.Series.accessorsOut:{‘cat’, ‘dt’, ‘str’}.cat用于分类数据,.str用于字符串(对象)数据,.dt用于类似日期时间的数据。让我们从.str开始看:假设现在我们有一些原始的城市/州/ 邮编数据作为Dataframe的一个字段:addr = pd.Series([ ‘Washington, D.C. 20003’, ‘Brooklyn, NY 11211-1755’, ‘Omaha, NE 68154’, ‘Pittsburgh, PA 15211’])addr.str.upper() # 因为字符串方法是矢量化的,这意味着它们在没有显式for循环的情况下对整个数组进行操作0 WASHINGTON, D.C. 200031 BROOKLYN, NY 11211-17552 OMAHA, NE 681543 PITTSBURGH, PA 15211dtype: objectaddr.str.count(r’\d’) # 查看邮编有几位0 51 92 53 5dtype: int64如果我们想把每一行分成城市,州,邮编分开,可以用正则;regex = (r’(?P<city>[A-Za-z ]+), ’ # One or more letters r’(?P<state>[A-Z]{2}) ’ # 2 capital letters r’(?P<zip>\d{5}(?:-\d{4})?)’) # Optional 4-digit extensionaddr.str.replace(’.’, ‘’).str.extract(regex) city state zip 0 Washington DC 20003 1 Brooklyn NY 11211-1755 2 Omaha NE 68154 3 Pittsburgh PA 15211 第二个访问器.dt用于类似日期时间的数据。它其实属于Pandas的DatetimeIndex,如果在Series上调用,它首先转换为DatetimeIndexdaterng = pd.Series(pd.date_range(‘2018’, periods=9, freq=‘Q’)) # 时间间隔为季度daterng0 2018-03-311 2018-06-302 2018-09-303 2018-12-314 2019-03-315 2019-06-306 2019-09-307 2019-12-318 2020-03-31dtype: datetime64[ns]daterng.dt.day_name()0 Saturday1 Saturday2 Sunday3 Monday4 Sunday5 Sunday6 Monday7 Tuesday8 Tuesdaydtype: objectdaterng[daterng.dt.quarter > 2] # 查看2019年第3季度和第4季度2 2018-09-303 2018-12-316 2019-09-307 2019-12-31dtype: datetime64[ns]daterng[daterng.dt.is_year_end] #查看年末的一天3 2018-12-317 2019-12-31dtype: datetime64[ns]最后有关.cat访问器我们会在第5个技巧中提到4. 合并其他列拼接DatetimeIndex现在先让我们构建一个包含时间类型数据的Dataframe:from itertools import productdatecols = [‘year’, ‘month’, ‘day’]df = pd.DataFrame(list(product([2017, 2016], [1, 2], [1, 2, 3])), columns=datecols)df[‘data’] = np.random.randn(len(df))df year month day data 0 2017 1 1 -0.0767 1 2017 1 2 -1.2798 2 2017 1 3 0.4032 3 2017 2 1 1.2377 4 2017 2 2 -0.2060 5 2017 2 3 0.6187 6 2016 1 1 2.3786 7 2016 1 2 -0.4730 8 2016 1 3 -2.1505 9 2016 2 1 -0.6340 10 2016 2 2 0.7964 11 2016 2 3 0.0005 我们可以发现year,month,day是分开的三列,我们如果想要把它们合并为完整的时间并作为df的索引,可以这么做:df.index = pd.to_datetime(df[datecols])df.head() year month day data 2017-01-01 2017 1 1 -0.0767 2017-01-02 2017 1 2 -1.2798 2017-01-03 2017 1 3 0.4032 2017-02-01 2017 2 1 1.2377 2017-02-02 2017 2 2 -0.2060 我们可以扔掉没用的列并把这个df压缩为Series:df = df.drop(datecols, axis=1).squeeze()df.head()2017-01-01 -0.07672017-01-02 -1.27982017-01-03 0.40322017-02-01 1.23772017-02-02 -0.2060Name: data, dtype: float64type(df)pandas.core.series.Seriesdf.index.dtype_str’datetime64[ns]‘5. 使用分类数据(Categorical Data)节省时间和空间刚刚我们在第3个技巧的时候提到了访问器,现在让我们来看最后一个.catpandas中Categorical这个数据类型非常强大,通过类型转换可以让我们节省变量在内存占用的空间,提高运算速度,不过有关具体的pandas加速实战,我会在下一期说,现在让我们来看一个小栗子:colors = pd.Series([ ‘periwinkle’, ‘mint green’, ‘burnt orange’, ‘periwinkle’, ‘burnt orange’, ‘rose’, ‘rose’, ‘mint green’, ‘rose’, ’navy’])import syscolors.apply(sys.getsizeof)0 591 592 613 594 615 536 537 598 539 53dtype: int64我们首先创建了一个Series,填充了各种颜色,接着查看了每个地址对应的颜色所占内存的大小注意这里我们使用sys.getsizeof()来获取占内存大小,但是实际上空格也是占内存的,sys.getsizeof(’’)返回的是49bytes接下来我们想把每种颜色用占内存更少的数字来表示(机器学习种非常常见),这样可以减少占用的内存,首先让我们创建一个mapper字典,给每一种颜色指定一个数字mapper = {v: k for k, v in enumerate(colors.unique())}mapper{‘periwinkle’: 0, ‘mint green’: 1, ‘burnt orange’: 2, ‘rose’: 3, ’navy’: 4}接着我们把刚才的colors数组转化为int类型:# 也可以通过 pd.factorize(colors)[0] 实现as_int = colors.map(mapper)as_int0 01 12 23 04 25 36 37 18 39 4dtype: int64再让我们看一下占用的内存:as_int.apply(sys.getsizeof)0 241 282 283 244 285 286 287 288 289 28dtype: int64现在可以观察到我们的内存占用的空间几乎是之前的一半,其实,刚刚我们做的正是模拟Categorical Data的转化原理。现在让我们直接调用一下:colors.memory_usage(index=False, deep=True)Out:650colors.astype(‘category’).memory_usage(index=False, deep=True)Out: 495大家可能感觉节省的空间并不是非常大对不对? 因为目前我们这个数据根本不是真实场景,我们仅仅把数据容量增加10倍,现在再让我们看看效果:manycolors = colors.repeat(10)len(manycolors) / manycolors.nunique() # Much greater than 2.0x Out:20.0f"Not using category : { manycolors.memory_usage(index=False, deep=True)}"‘Not using category : 6500’f"Using category : { manycolors.astype(‘category’).memory_usage(index=False, deep=True)}"‘Using category : 585’这回内存的占用量差距明显就出来了,现在让我们用.cat来简化一下刚刚的工作:new_colors = colors.astype(‘category’)new_colors0 periwinkle1 mint green2 burnt orange3 periwinkle4 burnt orange5 rose6 rose7 mint green8 rose9 navydtype: categoryCategories (5, object): [burnt orange, mint green, navy, periwinkle, rose]new_colors.cat.categories # 可以使用.cat.categories查看代表的颜色Index([‘burnt orange’, ‘mint green’, ’navy’, ‘periwinkle’, ‘rose’], dtype=‘object’)现在让我们查看把颜色代表的数字:new_colors.cat.codes0 31 12 03 34 05 46 47 18 49 2dtype: int8我们如果不满意顺序也可以从新排序:new_colors.cat.reorder_categories(mapper).cat.codes0 01 12 23 04 25 36 37 18 39 4dtype: int8有关cat其他的方法,我们还是可以通过遍历dir来查看:[i for i in dir(new_colors.cat) if not i.startswith(’’)][‘add_categories’, ‘as_ordered’, ‘as_unordered’, ‘categories’, ‘codes’, ‘ordered’, ‘remove_categories’, ‘remove_unused_categories’, ‘rename_categories’, ‘reorder_categories’, ‘set_categories’]Categorical 数据通常不太灵活,比如我们不能直接在new_colors上新增一个新的颜色,要首先通过.add_categories来添加ccolors.iloc[5] = ‘a new color’—————————————————————————NameError Traceback (most recent call last)<ipython-input-36-1766a795336d> in <module>()—-> 1 ccolors.iloc[5] = ‘a new color’NameError: name ‘ccolors’ is not definednew_colors = new_colors.cat.add_categories([‘a new color’])new_colors.iloc[5] = ‘a new color’ # 不会报错new_colors.values # 成功添加6. 利用Mapping巧妙实现映射假设现在我们有存贮国家的一组数据,和一组用来映射国家所对应的大洲的数据:countries = pd.Series([ ‘United States’, ‘Canada’, ‘Mexico’, ‘Belgium’, ‘United Kingdom’, ‘Thailand’])groups = { ‘North America’: (‘United States’, ‘Canada’, ‘Mexico’, ‘Greenland’), ‘Europe’: (‘France’, ‘Germany’, ‘United Kingdom’, ‘Belgium’)}我们可以通过下面的方法来实现简单的映射:from typing import Anydef membership_map(s: pd.Series, groups: dict, fillvalue: Any=-1) -> pd.Series: # Reverse & expand the dictionary key-value pairs groups = {x: k for k, v in groups.items() for x in v} return s.map(groups).fillna(fillvalue) membership_map(countries, groups, fillvalue=‘other’)很简单对不对,现在让我们看一下最关键的一行代码,groups = {x: k for k, v in groups.items() for x in v},这个是我之前提到过的字典推导式:test = dict(enumerate((‘ab’, ‘cd’, ‘xyz’))){x: k for k, v in test.items() for x in v}7. 压缩pandas对象如果你的pandas版本大于0.21.0,那么都可以直接把pandas用压缩形式写入,常见的类型有gzip, bz2, zip,这里我们直接用刚才鲍鱼的数据集:abalone.to_json(‘df.json.gz’, orient=‘records’,lines=True, compression=‘gzip’) # 压缩为gz类型abalone.to_json(‘df.json’, orient=‘records’, lines=True) #压缩为jsonimport os.pathos.path.getsize(‘df.json’) / os.path.getsize(‘df.json.gz’) #压缩大小差了10倍,还是gz更厉害8. 源码及GitHub地址这一期为大家总结了很多pandas实用的小技巧,希望大家喜欢我把这一期的ipynb文件和py文件放到了Github上,大家如果想要下载可以点击下面的链接:Github仓库地址: https://github.com/yaozeliang/pandas_share这一期就到这里啦,希望大家能够继续支持我,完结,撒花 ...

March 19, 2019 · 5 min · jiezi

Pandas之旅(三)最实用的Merge, Join,Concat方法详解

Merge, Join, Concat大家好,我有回来啦,这周更新的有点慢,主要是因为我更新了个人简历哈哈,如果感兴趣的朋友可以去看看哈:我的主页个人认为还是很漂亮的~,不得不说,很多时候老外的设计能力还是很强。好了,有点扯远了,这一期我想和大家分享的是pandas中最常见的几种方法,这些方法如果你学会了,某种程度上可以很好的替代Excel,这篇文章是pandas之旅的第三篇,主要会从以下几个方面和大家分享我的心得体会:MergeJoinConcat源码及GitHub地址话不多说,让我们开始今天的Pandas之旅吧!1. Merge首先merge的操作非常类似sql里面的join,实现将两个Dataframe根据一些共有的列连接起来,当然,在实际场景中,这些共有列一般是Id,连接方式也丰富多样,可以选择inner(默认),left,right,outer 这几种模式,分别对应的是内连接,左连接,右连接1.1 InnerMerge (内连接)首先让我们简单的创建两个DF,分别为DataFrame1,DataFrame2,他们的公有列是keyimport numpy as npimport pandas as pdfrom pandas import Series, DataFrame# Let’s make a dframedframe1 = DataFrame({‘key’:[‘X’,‘Z’,‘Y’,‘Z’,‘X’,‘X’],‘value_df1’: np.arange(6)})dframe1 key value_df1 0 X 0 1 Z 1 2 Y 2 3 Z 3 4 X 4 5 X 5 #Now lets make another dframedframe2 = DataFrame({‘key’:[‘Q’,‘Y’,‘Z’],‘value_df2’:[1,2,3]})dframe2 key value_df2 0 Q 1 1 Y 2 2 Z 3 我们现在可以简单地使用pd.merge(dframe1,dframe2)来实现Merge功能pd.merge(dframe1,dframe2) key value_df1 value_df2 0 Z 1 3 1 Z 3 3 2 Y 2 2 我们现在需要注意一点,X仅仅是存在于dframe1的key,在dframe2中不存在,因此大家可以发现,当我们调用pd.merge的时候,会自动默认为inner join,我们再换一种方式写一下,大家就明白了:pd.merge(dframe1,dframe2,on=‘key’,how=‘inner’) key value_df1 value_df2 0 Z 1 3 1 Z 3 3 2 Y 2 2 大家可以发现结果是一样的,看到这里,对sql熟悉的朋友们已经有感觉了估计,因为实在是太像了,如果我们不通过on和how来指定想要merge的公有列或者方式,那么pd.merge就会自动寻找到两个DataFrame的相同列并自动默认为inner join,至此,估计大家也可以猜出其他几种模式的merge啦1.2 LeftMerge (左连接)现在同样的,让我们看一下how=‘left’的情况,这是一个左连接pd.merge(dframe1,dframe2,on=‘key’,how=‘left’) key value_df1 value_df2 0 X 0 NaN 1 Z 1 3.0 2 Y 2 2.0 3 Z 3 3.0 4 X 4 NaN 5 X 5 NaN 我们可以看到返回的是dframe1的所有key值对应的结果,如果在dframe2中不存在,显示为Nan空值1.3 RightMerge (右连接)右连接的原理和左连接正相反pd.merge(dframe1,dframe2,on=‘key’,how=‘right’) key value_df1 value_df2 0 Z 1.0 3 1 Z 3.0 3 2 Y 2.0 2 3 Q NaN 1 这里Q只存在于drame2的key中1.4 OuterMerge (全连接)#Choosing the “outer” method selects the union of both keyspd.merge(dframe1,dframe2,on=‘key’,how=‘outer’) key value_df1 value_df2 0 X 0.0 NaN 1 X 4.0 NaN 2 X 5.0 NaN 3 Z 1.0 3.0 4 Z 3.0 3.0 5 Y 2.0 2.0 6 Q NaN 1.0 这里就是一个并集的形式啦,其实就是一个union的结果,会把key这一列在两个Dataframe出现的所有值全部显示出来,如果有空值显示为Nan1.5 MultipleKey Merge (基于多个key上的merge)刚才我们都是仅仅实现的在一个key上的merge,当然我们也可以实现基于多个keys的merge# Dframe on leftdf_left = DataFrame({‘key1’: [‘SF’, ‘SF’, ‘LA’], ‘key2’: [‘one’, ’two’, ‘one’], ’left_data’: [10,20,30]})df_left key1 key2 left_data 0 SF one 10 1 SF two 20 2 LA one 30 #Dframe on rightdf_right = DataFrame({‘key1’: [‘SF’, ‘SF’, ‘LA’, ‘LA’], ‘key2’: [‘one’, ‘one’, ‘one’, ’two’], ‘right_data’: [40,50,60,70]})df_right key1 key2 right_data 0 SF one 40 1 SF one 50 2 LA one 60 3 LA two 70 这是内连接(交集)的结果#Merge, Innerpd.merge(df_left, df_right, on=[‘key1’, ‘key2’]) key1 key2 left_data right_data 0 SF one 10 40 1 SF one 10 50 2 LA one 30 60 这是外连接(并集)的结果#Merge, Outerpd.merge(df_left, df_right, on=[‘key1’, ‘key2’],how=‘outer’) key1 key2 left_data right_data 0 SF one 10.0 40.0 1 SF one 10.0 50.0 2 SF two 20.0 NaN 3 LA one 30.0 60.0 4 LA two NaN 70.0 这里还有一个地方非常有意思,大家可以发现现在df_left,df_right作为key的两列分别是key1和key2,它们的名字是相同的,刚刚我们是通过制定on=[‘key1’, ‘key2’],那如果我们只指定一列会怎么样呢?pd.merge(df_left,df_right,on=‘key1’) key1 key2_x left_data key2_y right_data 0 SF one 10 one 40 1 SF one 10 one 50 2 SF two 20 one 40 3 SF two 20 one 50 4 LA one 30 one 60 5 LA one 30 two 70 大家可以看到pandas自动把key2这一列拆分成了key2_x和key2_y,都会显示在最后的merge结果里,如果我们想要给这两列重新命名,也是很容易的:# We can also specify what the suffix becomespd.merge(df_left,df_right, on=‘key1’,suffixes=(’_lefty’,’_righty’)) key1 key2_lefty left_data key2_righty right_data 0 SF one 10 one 40 1 SF one 10 one 50 2 SF two 20 one 40 3 SF two 20 one 50 4 LA one 30 one 60 5 LA one 30 two 70 像这样,我们可以通过suffixes参数来指定拆分的列的名字。1.6 Merge on Index (基于index上的merge)我们还可以实现几个Dataframe基于Index的merge,还是老样子,先让我们创建两个Dataframedf_left = DataFrame({‘key’: [‘X’,‘Y’,‘Z’,‘X’,‘Y’], ‘data’: range(5)})df_right = DataFrame({‘group_data’: [10, 20]}, index=[‘X’, ‘Y’])df_left key data 0 X 0 1 Y 1 2 Z 2 3 X 3 4 Y 4 df_right group_data X 10 Y 20 好了,现在我们想要实现两个Dataframe的merge,但是条件是通过df_left的Key和df_right的Indexpd.merge(df_left,df_right,left_on=‘key’,right_index=True) key data group_data 0 X 0 10 3 X 3 10 1 Y 1 20 4 Y 4 20 这样我们也可以得到结果。# We can also get a union by using outerpd.merge(df_left,df_right,left_on=‘key’,right_index=True,how=‘outer’) key data group_data 0 X 0 10.0 3 X 3 10.0 1 Y 1 20.0 4 Y 4 20.0 2 Z 2 NaN 其他的merge方式就类似啦,这里就不一一说了,只是举一个outer join的例子# 通过outer实现外连接,union并集pd.merge(df_left,df_right,left_on=‘key’,right_index=True,how=‘outer’) key data group_data 0 X 0 10.0 3 X 3 10.0 1 Y 1 20.0 4 Y 4 20.0 2 Z 2 NaN 我们也可以尝试一些有意思的merge,比如,如果一个dataframe的index是多层嵌套的情况:df_left_hr = DataFrame({‘key1’: [‘SF’,‘SF’,‘SF’,‘LA’,‘LA’], ‘key2’: [10, 20, 30, 20, 30], ‘data_set’: np.arange(5.)})df_right_hr = DataFrame(np.arange(10).reshape((5, 2)), index=[[‘LA’,‘LA’,‘SF’,‘SF’,‘SF’], [20, 10, 10, 10, 20]], columns=[‘col_1’, ‘col_2’])df_left_hr key1 key2 data_set 0 SF 10 0.0 1 SF 20 1.0 2 SF 30 2.0 3 LA 20 3.0 4 LA 30 4.0 df_right_hr col_1 col_2 LA 20 0 1 10 2 3 SF 10 4 5 10 6 7 20 8 9 现在我们穿建了两个Dataframe 分别是df_left_hr和df_right_hr(Index两层),如果我们想通过使用df_left_hr的key1,key2 及df_right_hr的Index作为merge的列,也是没有问题的# Now we can merge the left by using keys and the right by its indexpd.merge(df_left_hr,df_right_hr,left_on=[‘key1’,‘key2’],right_index=True) key1 key2 data_set col_1 col_2 0 SF 10 0.0 4 5 0 SF 10 0.0 6 7 1 SF 20 1.0 8 9 3 LA 20 3.0 0 1 基本到这里,我已经和大家分享了基础的Merge有关的所有操作,如果你平时生活工作中经常使用Excel执行类似操作的话,可以学习一下Merge哈,它会大幅度减轻你的工作强度的!2.Join现在我们可以接着来看join相关的操作,先让我们看一个小例子left = pd.DataFrame({‘A’: [‘A0’, ‘A1’, ‘A2’, ‘A3’], ‘B’: [‘B0’, ‘B1’, ‘B2’, ‘B3’]}, index = [‘K0’, ‘K1’, ‘K2’, ‘K3’]) right = pd.DataFrame({‘C’: [‘C0’, ‘C1’, ‘C2’, ‘C3’], ‘D’: [‘D0’, ‘D1’, ‘D2’, ‘D3’]}, index = [‘K0’, ‘K1’, ‘K2’, ‘K3’]) left A B K0 A0 B0 K1 A1 B1 K2 A2 B2 K3 A3 B3 right C D K0 C0 D0 K1 C1 D1 K2 C2 D2 K3 C3 D3 left.join(right) A B C D K0 A0 B0 C0 D0 K1 A1 B1 C1 D1 K2 A2 B2 C2 D2 K3 A3 B3 C3 D3 其实通过这一个小例子大家也就明白了,join无非就是合并,默认是横向,还有一个点需要注意的是,我们其实可以通过join实现和merge一样的效果,但是为了避免混淆,我不会多举其他的例子了,因为我个人认为一般情况下还是用merge函数好一些3. Concat为了更加全面彻底地了解Concat函数,大家可以先从一维的Numpy Array开始,首先让我们简单的创建一个矩阵:# Create a matrix arr1 = np.arange(9).reshape((3,3))arr1array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])接着让我们通过concatenate函数进行横向拼接:np.concatenate([arr1,arr1],axis=1)array([[0, 1, 2, 0, 1, 2], [3, 4, 5, 3, 4, 5], [6, 7, 8, 6, 7, 8]])再让我们进行纵向拼接:# Let’s see other axis optionsnp.concatenate([arr1,arr1],axis=0)array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 1, 2], [3, 4, 5], [6, 7, 8]])有了基础的印象之后,现在让我们看看在pandas中是如何操作的:# Lets create two Series with no overlapser1 = Series([0,1,2],index=[‘T’,‘U’,‘V’])ser2 = Series([3,4],index=[‘X’,‘Y’])#Now let use concat (default is axis=0)pd.concat([ser1,ser2])T 0U 1V 2X 3Y 4dtype: int64在上面的例子中,我们分别创建了两个没有重复Index的Series,然后用concat默认的把它们合并在一起,这时生成的依然是Series类型,如果我们把axis换成1,那生成的就是Dataframe,像下面一样pd.concat([ser1,ser2],axis=1,sort =True) # sort=Ture是默认的,pandas总是默认index排序 0 1 T 0.0 NaN U 1.0 NaN V 2.0 NaN X NaN 3.0 Y NaN 4.0 我们还可以指定在哪些index上进行concat:pd.concat([ser1,ser2],axis=1,join_axes=[[‘U’,‘V’,‘Y’]]) 0 1 U 1.0 NaN V 2.0 NaN Y NaN 4.0 也可以给不同组的index加一层标签pd.concat([ser1,ser2],keys=[‘cat1’,‘cat2’])cat1 T 0 U 1 V 2cat2 X 3 Y 4dtype: int64如果把axis换成是1,那么keys就会变成column的名字:pd.concat([ser1,ser2],axis=1,keys=[‘cat1’,‘cat2’],sort=True) cat1 cat2 T 0.0 NaN U 1.0 NaN V 2.0 NaN X NaN 3.0 Y NaN 4.0 如果是两个现成的dataframe直接进行concat也是一样:dframe1 = DataFrame(np.random.randn(4,3), columns=[‘X’, ‘Y’, ‘Z’])dframe2 = DataFrame(np.random.randn(3, 3), columns=[‘Y’, ‘Q’, ‘X’])dframe1 X Y Z 0 1.119976 -0.853960 0.027451 1 -0.536831 0.982092 -0.157650 2 -0.219322 -1.489809 1.607735 3 0.767249 -1.661912 0.038837 dframe2 Y Q X 0 -0.035560 0.875282 -1.630508 1 -0.439484 0.096247 1.335693 2 0.746299 0.568684 1.197015 #如果没有对应的值,默认为NaN, 空值pd.concat([dframe1,dframe2],sort=True) Q X Y Z 0 NaN 1.119976 -0.853960 0.027451 1 NaN -0.536831 0.982092 -0.157650 2 NaN -0.219322 -1.489809 1.607735 3 NaN 0.767249 -1.661912 0.038837 0 0.875282 -1.630508 -0.035560 NaN 1 0.096247 1.335693 -0.439484 NaN 2 0.568684 1.197015 0.746299 NaN 4. 源码及Github地址今天我为大家主要总结了pandas中非常常见的三种方法:mergeconcatjoin大家可以根据自己的实际需要来决定使用哪一种我把这一期的ipynb文件和py文件放到了Github上,大家如果想要下载可以点击下面的链接:Github仓库地址: https://github.com/yaozeliang/pandas_share这一期就到这里啦,希望大家能够继续支持我,完结,撒花 ...

March 17, 2019 · 5 min · jiezi

[译]如何根据条件从pandas DataFrame中删除不需要的行?

问题来源:https://stackoverflow.com/que…问:我有一个pandas DataFrame,我想删除它特定列中字符串差姑娘是大于2的行,我知道我可以使用df.dropna()来去除包含NaN的行,但我没有找到如何根据条件删除行。似乎我能够这样做:df[(len(df[‘column name’]) < 2)]但却报错了:KeyError: u’no item named False’谁能告诉我错在哪里了?回答一:当你这样做时,len(df[‘column name’])你只得到一个数字,即DataFrame中的行数(即列本身的长度)。如果要应用于len列中的每个元素,请使用df[‘column name’].map(len)。尝试使用:df[df[‘column name’].map(len) < 2]评论:我想出了一种使用列表解析的方法:df[[(len(x) < 2) for x in df[‘column name’]]] 但是你这种方法更好些。回答二:要直接回答这个问题,一种方法是使用drop方法:df = df.drop(some labels)df = df.drop(df[<some boolean condition>].index)要删除列“score”<50的所有行:df = df.drop(df[df.score < 50].index)替换版本df.drop(df[df.score < 50].index, inplace=True)多条件情况:可以使用操作符: | 只需其中一个成立, & 同时成立, ~ 表示取反,它们要用括号括起来。例如删除列“score<50 和>20的所有行df = df.drop(df[(df.score < 50) & (df.score > 20)].index)

March 12, 2019 · 1 min · jiezi

Pandas之旅(二): 有关数据清理的点点滴滴

数据清洗大家好,这一期我将为大家带来我的pandas学习心得第二期:数据清理。这一步非常重要,一般在获取数据源之后,我们紧接着就要开始这一步,以便为了之后的各种操作,简单来说,我们的目标就是让数据看起来赏心悦目,规规矩矩的,所以我们会对原始的dataframe做一些必要的美容,包括规范命名,去除异常值,重新选择合适的index啊,处理缺失值,统一列的命名等等。这一期我会和大家分享一些比较好用常见的清洗方法。首先还是让我们来简单看一下本文将会用到的数据源:property_data.csv 这是一个超小型的房地产行业的数据集,大家会在文章最后找到下载地址。这篇文章我会从以下几个方面来和大家分享我的心得体会:有关缺失值的处理有关列的处理设置Index源码及数据下载地址1.有关缺失值的处理这里我们会用到 property_data.csv这个数据集,在开始处理缺失值之前,我们可以先话一分钟仔细想想,为什么实际生活中的数据从来是不完整的,原因基本有几个方面:用户忘记填写字段从旧数据库手动传输时数据丢失代码中有bug用户不填写非必须字段(比如注册的时候)因为这些原因,我每次在处理missing value的时候都会问自己两个基础问题:数据集每一列有什么特点?我们想要在处理后得到什么类型的数据(int,float,string,boolean)?带着这些疑问,我们可以开始了,首先让我们简单读取一下数据,利用head函数看看前5行,如果你还对pandas的基础知识有疑问,可以看看我上一篇文章:Pandas之旅(一): 让我们把基础知识一次撸完,申精干货import pandas as pdimport numpy as npimport osos.chdir(“F:\Python教程\segmentfault\pandas_share\Pandas之旅_02 数据清洗”)# Read csv file into a pandas dataframedf = pd.read_csv(“property_data.csv”)# Take a look at the first few rowsdf.head() PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT 0 100001000.0 104.0 PUTNAM Y 3 1 1000 1 100002000.0 197.0 LEXINGTON N 3 1.5 – 2 100003000.0 NaN LEXINGTON N NaN 1 850 3 100004000.0 201.0 BERKELEY 12 1 NaN 700 4 NaN 203.0 BERKELEY Y 3 2 1600 现在让我们看看数据的一些关键列是什么:ST_NUM:街道号码ST_NAME: 街道名称OWN_OCCUPIED: 是否用于自住NUM_BEDROOMS:卧室数量SQ_FT:面积这里可以给大家普及点房地产知识,有的时候房屋用途被明确规定,比如有的房产写的是"owner occupied only “)意思是说如果你买了,那这个房子会成为你的主要住所,不能用于出租之类的,简单理解就是自住所以现在我可以自问自答第一个问题:数据集每一列有什么特点?ST_NUM:float或int …ST_NAME:stringOWN_OCCUPIED:string … Y(“是”)或N(“否”)NUM_BEDROOMS:float或int,数字类型SQ_FT:float或int,数字类型1.1 规范的缺失值标记现在让我们关注ST_NUM这一列:# Looking at the ST_NUM columndf[‘ST_NUM’]0 104.01 197.02 NaN3 201.04 203.05 207.06 NaN7 213.08 215.0Name: ST_NUM, dtype: float64如果想查看该列的缺失值情况,我们可以利用isnull()方法,如果出现缺失值,会返回True,反之返回falsedf[‘ST_NUM’].isnull()0 False1 False2 True3 False4 False5 False6 True7 False8 FalseName: ST_NUM, dtype: bool但是其实如果我们打开csv文件,你会发现第3行是空白,还有一行在该列显示的是NA,所以结论已经有了:在pandas里表示缺省值的符号及时NA,换句话说,如果我们要表示缺省值,标准写法是NA1.2 不规范的缺失值标记同样的,这回让我们关注一下NUM_BEDROOMS这一列,我们发现出现了4种类型的表达缺省值的标记:n/aNA—na通过刚才的实践,我们已经确定NA是pandas可以识别的,那么其他的符号呢,现在让我们来测试一下df[‘NUM_BEDROOMS’]0 31 32 NaN3 14 35 NaN6 27 18 naName: NUM_BEDROOMS, dtype: objectdf[‘NUM_BEDROOMS’].isnull()0 False1 False2 True3 False4 False5 True6 False7 False8 FalseName: NUM_BEDROOMS, dtype: bool可以看到pandas识别了n/a 和NA两种符号,但是接下来我们要考虑一个问题,假设你是房地产公司的地区总经理,你每周会收到不同地区的负责人提交的表格,这些人中有的喜欢用–表示空白值,有的人喜欢用na,那应该怎么办?最简单的方式就是将所有表示空白值的符号统一放在list中,让后让pandas一次性识别:# Making a list of missing value typesmissing_values = [“na”, “–"]df = pd.read_csv(“property_data.csv”, na_values = missing_values)现在我们来看看到底发生了什么?df PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT 0 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 1 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN 2 100003000.0 NaN LEXINGTON N NaN 1 850.0 3 100004000.0 201.0 BERKELEY 12 1.0 NaN 700.0 4 NaN 203.0 BERKELEY Y 3.0 2 1600.0 5 100006000.0 207.0 BERKELEY Y NaN 1 800.0 6 100007000.0 NaN WASHINGTON NaN 2.0 HURLEY 950.0 7 100008000.0 213.0 TREMONT Y 1.0 1 NaN 8 100009000.0 215.0 TREMONT Y NaN 2 1800.0 我们可以发现只要missing_value中记录的表达空白值的符号,全部变成了规整的NaN1.3 类型不一致的异常值刚刚我们已经简单了解了在pandas中如何处理缺失值的,还有一种情况,让我们来看OWN_OCCUPIED这一列,这一列的答案只能是Y,N 但是我们发现数据集意外地出现了12,属于类型不对称df[‘OWN_OCCUPIED’].isnull()0 False1 False2 False3 False4 False5 False6 True7 False8 FalseName: OWN_OCCUPIED, dtype: bool现在我们发现12是异常值,因为它是类型错误,所以我们可以简单通过下面这个方法来检测,# Detecting numbers cnt=0for row in df[‘OWN_OCCUPIED’]: try: int(row) df.loc[cnt, ‘OWN_OCCUPIED’]=np.nan except ValueError: pass cnt+=1我们这里的策略是:循环遍历OWN_OCCUPIED列尝试将条目转换为整数如果条目可以更改为整数,请输入缺失值如果数字不能是整数,我们知道它是一个字符串,所以继续这样我们会把OWN_OCCUPIED这一列中所有类型不对的值转化为NaN,现在来看结果:df[‘OWN_OCCUPIED’]0 Y1 N2 N3 NaN4 Y5 Y6 NaN7 Y8 YName: OWN_OCCUPIED, dtype: object1.4 汇总缺失值pandas提供了更为简洁的方式,可以让我们整体了解所有column的空值:df.isnull().sum()PID 1ST_NUM 2ST_NAME 0OWN_OCCUPIED 2NUM_BEDROOMS 3NUM_BATH 1SQ_FT 2dtype: int64或者如果我们只想知道数据是否存在空值,那么可以使用以下的命令:# Any missing values?df.isnull().values.any()True1.5 替换缺失值如果我们想要替换掉缺失值,可以用fillna方法# Replace missing values with a numberdf[‘ST_NUM’].fillna(125, inplace=True)或者我们可以通过准确定位来替换缺失值:# Location based replacementdf.loc[2,‘ST_NUM’] = 125替换缺失值的一种非常常见的方法是使用中位数:# Replace using median median = df[‘NUM_BEDROOMS’].median()df[‘NUM_BEDROOMS’].fillna(median, inplace=True)df PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT 0 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 1 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN 2 100003000.0 125.0 LEXINGTON N 2.5 1 850.0 3 100004000.0 201.0 BERKELEY NaN 1.0 NaN 700.0 4 NaN 203.0 BERKELEY Y 3.0 2 1600.0 5 100006000.0 207.0 BERKELEY Y 2.5 1 800.0 6 100007000.0 125.0 WASHINGTON NaN 2.0 HURLEY 950.0 7 100008000.0 213.0 TREMONT Y 1.0 1 NaN 8 100009000.0 215.0 TREMONT Y 2.5 2 1800.0 2. 有关列的处理2.1 统一修改列名现在假设因为一些需求,需要我们统一修改列名,把列名改为小写,我们可以结合列表推导式轻易实现df.rename(str.lower, axis=‘columns’,inplace =True)df.columnsIndex([‘pid’, ‘st_num’, ‘st_name’, ‘own_occupied’, ’num_bedrooms’, ’num_bath’, ‘sq_ft’], dtype=‘object’)或者需要把列名中的_改为-:new_cols = [c.replace(”_”,"-") for c in df.columns]change_dict =dict(zip(df.columns,new_cols))df.rename(columns=change_dict,inplace=True)df pid st-num st-name own-occupied num-bedrooms num-bath sq-ft 0 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 1 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN 2 100003000.0 125.0 LEXINGTON N 2.5 1 850.0 3 100004000.0 201.0 BERKELEY NaN 1.0 NaN 700.0 4 NaN 203.0 BERKELEY Y 3.0 2 1600.0 5 100006000.0 207.0 BERKELEY Y 2.5 1 800.0 6 100007000.0 125.0 WASHINGTON NaN 2.0 HURLEY 950.0 7 100008000.0 213.0 TREMONT Y 1.0 1 NaN 8 100009000.0 215.0 TREMONT Y 2.5 2 1800.0 这里我没有写的精简一些,反而是复杂了,主要是想让大家回忆起之前我分享的dict使用技巧中的内容,注意这里inplace=True,导致的结果是我们的的确确修改了df所有的列名2.1 根据需求新增列假如目前我们需要新增一列,根据房屋面积大小来赋值,我们先随意把缺失值补上:df[‘sq-ft’].fillna(‘0.0’)0 10001 0.02 8503 7004 16005 8006 9507 0.08 1800Name: sq-ft, dtype: object然后新建一列rank来根据房屋面积大小赋值S=small,M=medium,B=big:df[“rank”]= pd.cut(df[‘sq-ft’], [0, 800, 1600, np.inf], labels=(“S”,“M”,“B”))df pid st-num st-name own-occupied num-bedrooms num-bath sq-ft rank 0 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 M 1 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN NaN 2 100003000.0 125.0 LEXINGTON N 2.5 1 850.0 M 3 100004000.0 201.0 BERKELEY NaN 1.0 NaN 700.0 S 4 NaN 203.0 BERKELEY Y 3.0 2 1600.0 M 5 100006000.0 207.0 BERKELEY Y 2.5 1 800.0 S 6 100007000.0 125.0 WASHINGTON NaN 2.0 HURLEY 950.0 M 7 100008000.0 213.0 TREMONT Y 1.0 1 NaN NaN 8 100009000.0 215.0 TREMONT Y 2.5 2 1800.0 B 具体实现方法我们之后会说,这里主要是用到了pandas的cut方法,非常便捷3. 设置Index在许多情况下,使用数据的唯一值标识字段作为其索引是有帮助的。这里可能我们的数据不太合适,因此我们先伪造一列Fake_Index来模拟真实场景中的真正索引df[“Fake_Index”]=[“A00”+str(i) for i in range(len(df))]df pid st-num st-name own-occupied num-bedrooms num-bath sq-ft rank Fake_Index 0 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 M A000 1 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN NaN A001 2 100003000.0 125.0 LEXINGTON N 2.5 1 850.0 M A002 3 100004000.0 201.0 BERKELEY NaN 1.0 NaN 700.0 S A003 4 NaN 203.0 BERKELEY Y 3.0 2 1600.0 M A004 5 100006000.0 207.0 BERKELEY Y 2.5 1 800.0 S A005 6 100007000.0 125.0 WASHINGTON NaN 2.0 HURLEY 950.0 M A006 7 100008000.0 213.0 TREMONT Y 1.0 1 NaN NaN A007 8 100009000.0 215.0 TREMONT Y 2.5 2 1800.0 B A008 现在我们添加的最后一列非常像真正的房屋Id了,让我们来看看这个伪造的索引是不是唯一值,可以利用is_unique来检验:df.Fake_Index.is_uniqueTrue没有问题,现在我们可以放心地把这列设置为我们真正的索引:df = df.set_index(‘Fake_Index’)df pid st-num st-name own-occupied num-bedrooms num-bath sq-ft rank Fake_Index A000 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 M A001 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN NaN A002 100003000.0 125.0 LEXINGTON N 2.5 1 850.0 M A003 100004000.0 201.0 BERKELEY NaN 1.0 NaN 700.0 S A004 NaN 203.0 BERKELEY Y 3.0 2 1600.0 M A005 100006000.0 207.0 BERKELEY Y 2.5 1 800.0 S A006 100007000.0 125.0 WASHINGTON NaN 2.0 HURLEY 950.0 M A007 100008000.0 213.0 TREMONT Y 1.0 1 NaN NaN A008 100009000.0 215.0 TREMONT Y 2.5 2 1800.0 B 现在对数据的操作容易多了,我们很多事情可以通过索引完成:# 根据索引名称切片df[‘A000’:‘A003’] pid st-num st-name own-occupied num-bedrooms num-bath sq-ft rank Fake_Index A000 100001000.0 104.0 PUTNAM Y 3.0 1 1000.0 M A001 100002000.0 197.0 LEXINGTON N 3.0 1.5 NaN NaN A002 100003000.0 125.0 LEXINGTON N 2.5 1 850.0 M A003 100004000.0 201.0 BERKELEY NaN 1.0 NaN 700.0 S # 根据索引位置切片df.iloc[1:3, 0:3] pid st-num st-name Fake_Index A001 100002000.0 197.0 LEXINGTON A002 100003000.0 125.0 LEXINGTON # 定位到具体元素df.iloc[1,2]‘LEXINGTON’总结我把这一期的ipynb文件和py文件放到了GIthub上,大家如果想要下载可以点击下面的链接:Github仓库地址: https://github.com/yaozeliang/pandas_share这一期先讲到这里,希望大家能够继续支持我,完结,撒花 ...

March 9, 2019 · 5 min · jiezi

Pandas之旅(一): 让我们把基础知识一次撸完,申精干货

为什么你需要pandas大家好,今天想和大家分享一下有关pandas的学习新的,我因工作需要,从去年12月开始接触这个非常好用的包,到现在为止也是算是熟悉了一些,因此发现了它的强大之处,特意想要和朋友们分享,特别是如果你每天和excel打交道,总是需要编写一些vba函数或者对行列进行groupby啊,merge,join啊之类的,相信我,pandas会让你解脱的。好啦,闲话少说,这篇文章的基础是假设你已经大概听说过了pandas的一些概念和用途,如果还大体上不太清楚的朋友们,可以去百度一下相关基础介绍,本分主要分成四个部分:从Dataframe说起 : 简单了解Df这种数据结构,了解如何创建一个DfDataframe基础操作 :基于行,列,index选取数据,新增数据,删除数据Pandas 读取 / 导出数据: 了解如何对excel,csv,tsv等常见文件进行读取并导出总结: 精华部分,为大家总结一些非常实用的一些方法,并附带源码 ipynb以及py文件提供下载1. 从Dataframe说起首先,让我们明确一点,pandas这个包是在numpy的基础上得到的,因此可能有的朋友会有疑问,要不要先学学numpy,我的个人建议是真的不太需要,因为大多数的情况下基本用不到,当然,如果你处理的是科学实验类型的数据的话,当我没说,我这里的应用场景主要是一般类型的常见数据,比如:你是销售经理,经常需要汇总各地区的销售情况你在银行工作,不可避免的需要和数字,excel打交道你每天有很多重复的工作,比如备份,计算两表合并,分组,聚类等等。。。。。。这种情况下,学习pandas会非常有用,这里我们说的数据都是二维的table,在pandas中也称作dataframe。pandas中其实一共有三种类型的常见数据:数据结构维度说明Series1类似list,一维数组Data Frames2最常见的二维数据结构,excel,sql的表就是这个Panel3用的很少,三维结构pandas主要包括三类数据结构,分别是:Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。Panel :三维的数组,可以理解为DataFrame的容器。Pandas官网,更多功能请参考 http://pandas-docs.github.io/…这里我们主要聚焦在Dataframe上,一个dataframe长的基本上如下这番模样:NameAgeMarkJohn1578Mike2386Mary3695我们把这个简单的dataframe起个名字叫df,那么它包括的最基础的元素有:index:每行的索引,默认是从0开始,比如上面的df[0] 就是指 John 15 78这一行,依次类推,当然我们可以自己规定index,我以后会说columns:列。这里就是指的是Name Age Mark 了rows:行,df一共有3行现在让我们看一个完整的图示:Dataframe 是应用最多也是最广泛的数据结构,现在就让我们开始学习创建一个dataframe吧~1.1 创建Dataframe创建一个Dataframe的方法有很多,总体上来说最常见的有及种:创建空dataframe利用dict创建从其他数据源读取(网站,excel,mysql等)真实场景中大多数都是从其他数据源读取,我们会在第3部分讲到创建空dataframe这个非常简单:import pandas as pd # Calling DataFrame constructor df = pd.DataFrame() print(df)Out:Empty DataFrame Columns: [] Index: []利用dict创建(1)import pandas as pdprint (f" Using {pd.name},Version {pd.version}")Out: Using pandas , version 0.23.4首先要import pandas 包,这里缩写为pd,现在让我们从dict创建一个dataframe:>>> dict = {’name’:[“Tom”, “Bob”, “Mary”, “James”], ‘age’: [18, 30, 25, 40], ‘city’:[“Beijing”, “ShangHai”,“GuangZhou”, “ShenZhen”]} >>> df = pd.DataFrame(dict) >>> df创建结果如下: age city name 0 18 Beijing Tom 1 30 ShangHai Bob 2 25 GuangZhou Mary 3 40 ShenZhen James 很简单是不是,大家可能发现了,最左边的东西就是index ,0,1,2,3,如果我们不指定会自动生成从0默认开始的序列,一直到你的dataframe的最后一行,类似于excel左边的编号利用dict创建(2)这次让我们创建的更加规范一些:index = pd.Index([“Tom”, “Bob”, “Mary”, “James”],name = ‘person’)cols = [‘age’,‘city’]data = [[18,‘Beijing’], [30,‘ShangHai’], [25,‘GuangZhou’], [40,‘ShenZhen’]]df =pd.DataFrame(index = index,data =data,columns = cols)df age city person Tom 18 Beijing Bob 30 ShangHai Mary 25 GuangZhou James 40 ShenZhen 这里的主要区别在于我们主动规定了‘name’列为索引。这种把一列默认为索引的方式在excel和sql里都有,异曲同工从其他数据源读取(网站,excel,mysql等)我会在第三部分介绍最常用的从excel,csv等读取数据总体来说,有关创建Dataframe的部分我们不用了解太多,因为实际的场景基本不需要,都是直接从csv,tsv,sql,json等数据源直接获取。2. Dataframe 基础操作这里我们主要看一下基于索引,行,列,行和列的基础操作,最后会为大家总结一下,现在拿刚刚我们创建过的dataframe为例: age city name 0 18 Beijing Tom 1 30 ShangHai Bob 2 25 GuangZhou Mary 3 40 ShenZhen James 2.1 对columns的基础操作添加新列添加一列非常简单:df[‘country’] = ‘USA’df age city name country 0 18 Beijing Tom USA 1 30 ShangHai Bob USA 2 25 GuangZhou Mary USA 3 40 ShenZhen James USA df[‘adress’] = df[‘country’]df age city name country adress 0 18 Beijing Tom USA USA 1 30 ShangHai Bob USA USA 2 25 GuangZhou Mary USA USA 3 40 ShenZhen James USA USA 修改列中的值修改一个列的值也是很容易的,我们可以这样做:df[‘country’] = ‘China’df age city name country adress 0 18 Beijing Tom China USA 1 30 ShangHai Bob China USA 2 25 GuangZhou Mary China USA 3 40 ShenZhen James China USA 或者稍微多想一步:df[‘adress’] = df[‘city’]+’,’+ df[‘country’]df age city name country adress 0 18 Beijing Tom China Beijing,China 1 30 ShangHai Bob China ShangHai,China 2 25 GuangZhou Mary China GuangZhou,China 3 40 ShenZhen James China ShenZhen,China 删除列我们可以应用del或者drop函数,如果是drop,要注意传参时要加上axis = 1.这里简单和大家说明一下axis,这个东西其实就是指轴向,默认的axis=0,是纵向,axis=1是横向df.drop(‘country’,axis=1)df age city name adress 0 18 Beijing Tom Beijing,China 1 30 ShangHai Bob ShangHai,China 2 25 GuangZhou Mary GuangZhou,China 3 40 ShenZhen James ShenZhen,China del df[‘city’]df age name adress 0 18 Tom Beijing,China 1 30 Bob ShangHai,China 2 25 Mary GuangZhou,China 3 40 James ShenZhen,China 这里有一点大家需要注意:drop和del的结果是基于df的两次单独操作,并不是连续的如果我们执行完drop后,重新查看df,这时你会发现df没有变化,因为没有真正的删除要想真正删除,需要加上关键字 inplace = True因此如果我们想要连续删除country和city这两列,改进后的代码如下:df.drop(‘country’,axis=1, inplace=True)del df[‘city’]df age name adress 0 18 Tom Beijing,China 1 30 Bob ShangHai,China 2 25 Mary GuangZhou,China 3 40 James ShenZhen,China 选取列这个非常简单,实现代码如下:df[‘age’] # 选取age这一列 0 18 1 30 2 25 3 40 Name: age, dtype: int64或者这样:df.name 0 Tom 1 Bob 2 Mary 3 James Name: name, dtype: object如果想要选取多个列也很容易,传递一个list就行啦:df[[‘age’,’name’]] age name 0 18 Tom 1 30 Bob 2 25 Mary 3 40 James 这里注意,和选取单独一列不同,这里我们返回的类型是dataframe,之前的类型是series,我们可以这么理解,一列其实还是一维数组,但是两列及以上是二维的了,当然类型也变了如果我们想要查看当前的所有列:df.columnsOut:Index([u’age’, u’name’, u’adress’], dtype=‘object’)如果我们想要重新对列进行命名,基本有三种方法,大家挑一种自己喜欢的就行传递list传递dict传递 axis用list:df.columns = [‘Age’,‘Name’,‘Adress’]df用dict:df.rename(index = str, columns = {‘age’:‘Age’,’name’:‘Name’,‘adress’:‘Adress’}) #这里index=str 有没有都行,我这么做是为了规范df用axis:df.rename(str.capitalize, axis=‘columns’,inplace =True)df最后得到的效果是一样的: Age Name Adress 0 18 Tom Beijing,China 1 30 Bob ShangHai,China 2 25 Mary GuangZhou,China 3 40 James ShenZhen,China 根据条件给列赋值我们现在想要根据人的年龄新增一列 Group,假设要求如下:18岁以下的是年轻人18-30的是中年人30以上的是老年人我们有很多方法可以实现,先看一种,大家可以先忽视loc方法,这里传达的就是基础思路:df[‘Group’] = ’elderly’df.loc[df[‘Age’]<=18, ‘Group’] = ‘young’df.loc[(df[‘Age’] >18) & (df[‘Age’] <= 30), ‘Group’] = ‘middle_aged’df Age Name Adress Group 0 18 Tom Beijing,China young 1 30 Bob ShangHai,China middle_aged 2 25 Mary GuangZhou,China middle_aged 3 40 James ShenZhen,China elderly 2.2 对 rows 的基础操作loc函数 df.loc[row,column]首先,大多数对于行的操作都可以通过loc函数实现,比如我们想要选取全部的行,除了直接打出df外,可以使用df.loc[:]df.loc[:] Age Name Adress Group 0 18 Tom Beijing,China young 1 30 Bob ShangHai,China middle_aged 2 25 Mary GuangZhou,China middle_aged 3 40 James ShenZhen,China elderly loc函数条件查询df.loc[df[‘Age’]>20] Name Age Adress Group 1 Bob 30 ShangHai,China middle_aged 2 Mary 25 GuangZhou,China middle_aged 3 James 40 ShenZhen,China elderly loc函数条件行列查询df.loc[df[‘Group’]==‘middle_aged’,‘Name’]1 Bob2 MaryName: Name, dtype: objectWhere 查询filter_adult = df[‘Age’]>25result = df.where(filter_adult)result Name Age Adress Group 0 NaN NaN NaN NaN 1 Bob 30.0 ShangHai,China middle_aged 2 NaN NaN NaN NaN 3 James 40.0 ShenZhen,China elderly Query 筛选# df.query(‘Age==30’) df.query(‘Group==“middle_aged”‘and ‘Age>30’ ) Name Age Adress Group 3 James 40 ShenZhen,China elderly 2.3 对 Dataframe 的基础了解这里有很多有用的方法,可以帮助到大家大致了解数据的情况:df.shape # 了解行列情况Out:(4, 4)df.describe() # 获取可计算列基础统计 Age count 4.000000 mean 28.250000 std 9.251126 min 18.000000 25% 23.250000 50% 27.500000 75% 32.500000 max 40.000000 # df.head(3) #查看前三行数据,默认为5df.tail(3) #获得最后三行数据 Name Age Adress Group 1 Bob 30 ShangHai,China middle_aged 2 Mary 25 GuangZhou,China middle_aged 3 James 40 ShenZhen,China elderly 3. Pandas读取导出数据(csv)Pandas 支持大部分常见数据文件读取与存储。一般清楚下,读取文件的方法以 pd.read_ 开头,而写入文件的方法以 pd.to_ 开头。这里我们开始熟悉一下最实用的对于csv文件的读取写入写入CSVdf.to_csv(‘person.csv’,index=None,sep=’,’)import osos.getcwd()Out: ‘C:\Users\E560’这样大家就可以在’C:UsersE560’的路径下找到我们刚刚生成的csv文件了,这里我把index=None,舍弃了索引值读取CSV首先我们确认和python文件同一目录下存在我们刚刚导出的person.csv文件,之后可以很容易的读取了:person = pd.read_csv(‘person.csv’)person Name Age Adress Group 0 Tom 18 Beijing,China young 1 Bob 30 ShangHai,China middle_aged 2 Mary 25 GuangZhou,China middle_aged 3 James 40 ShenZhen,China elderly 这时我们发现,即使我们读取的csv文件没有索引,但是pandas已经默认帮我们加上了4. 总结,资料下载好了,现在大家对pandas的使用已经有了基础的印象,我给大家简单总结一下常用的方法:使用标签选取数据df.loc[行标签,列标签]df.loc[‘Tom’:‘Mary’] #选取 Tom至Mary的所有行的数据,Tom和Mary是indexdf.loc[:,‘city’] #选取 city 列的数据df.loc 的第一个参数是行标签,第二个参数为列标签(可选参数,默认为所有列标签),两个参数既可以是列表也可以是单个字符,如果两个参数都为列表则返回的是 DataFrame,否则,则为 Series。PS:loc为location的缩写。使用位置(index)选取数据df.iloc[行位置,列位置] df.iloc[1,1] #选取第二行,第二列的值,返回的为单个值 df.iloc[[0,2],:] #选取第一行及第三行的数据 df.iloc[0:2,:] #选取第一行到第三行(不包含)的数据 df.iloc[:,1] #选取所有记录的第二列的值,返回的为一个Series df.iloc[1,:] #选取第一行数据,返回的为一个SeriesPS:iloc 则为 integer & location 的缩写通过逻辑指针进行数据切片df[逻辑条件]df[df.age >= 18] #单个逻辑条件df[(df.age >=18 ) & (df.country==‘China’) ] #多个逻辑条件组合了解并掌握数据大致情况方法解释count非na值的数量describe针对Series或个DataFrame列计算汇总统计min、max计算最小值和最大值argmin、argmax计算能够获取到最大值和最小值得索引位置(整数)idxmin、idxmax计算能够获取到最大值和最小值得索引值quantile计算样本的分位数(0到1)sum值的总和mean值得平均数median值得算术中位数(50%分位数)mad根据平均值计算平均绝对离差var样本值的方差std样本值的标准差skew样本值得偏度(三阶矩)kurt样本值得峰度(四阶矩)cumsum样本值得累计和cummin,cummax样本值得累计最大值和累计最小值cumprod样本值得累计积diff计算一阶差分(对时间序列很有用)pct_change计算百分数变化常见读取写入数据数据类型读取写入CSVread_csvto_csvJSONread_jsonto_jsonHTMLread_htmlto_htmlEXCELread_excelto_excelSQLread_sqlto_sql好了,其实这些就是想要告诉大家如何学习pandas,没有必要了解每一个方法,但是现在想必你知道pandas能实现的功能很多,这样你有具体需求时只要详细查询一下文档即可,接下来几期我们会重点来看pandas里面对于df的各种操作,从简单的数据清理到类似于excel里面的vba,包括cancat,merge,join等等下载我把这一期的ipynb文件和py文件放到了GIthub上,大家如果想要下载可以点击下面的链接:Github仓库地址: 点我下载好啦,这一期就讲这么多,希望大家能够继续支持我,完结,撒花 ...

March 4, 2019 · 4 min · jiezi

Python 进阶之路 (十二) 尾声即是开始

Python进阶之路总结大家好,我的<< Python进阶之路>>到这一期就到此为止了,和 <<Python 基础起步>>不同,在掌握了一些基础知识后,我在这一期里同步和大家分享了我的学习心得,一共主要关注了以下几个知识点:Python 进阶之路 (一) List 进阶方法汇总Python 进阶之路 (二) Dict 进阶宝典Python 进阶之路 (三) Tuple元组使用指南Python 进阶之路 (四) 先立Flag, 社区最全的Set用法集锦Python 进阶之路 (五) map, filter, reduce, zip 一网打尽Python 进阶之路 (六) 九浅一深 lambda,陈独秀你给我坐下!Python 进阶之路 (七) 隐藏的神奇宝藏:探秘CollectionsPython 进阶之路 (八) 最用心的推导式详解Python 进阶之路 (九) 再立Flag, 社区最全的itertools深度解析(上)Python 进阶之路 (十) 再立Flag, 社区最全的itertools深度解析(中)Python 进阶之路 (十一) 再立Flag, 社区最全的itertools深度解析(下)现在看来,除了标题起的比较活泼外,考虑到我也是小白,内容上我自认为已经是干货满满了,如果你打开任何一篇文章,相信你会发现我并没有夸大,没有任何一篇文章是蜻蜓点水,一带而过,对得起花时间观看文章的每一位朋友,从2月4日第一遍笔记起,22天更新了11篇,应该说高产似母猪了今天是进阶之路的最后一篇文章,然而像标题所示,尾声即是开始,现在我们中午掌握了python的基础知识,哪怕可能不够熟练,但是足够开始新的征程了!我决定新的旅途让我们从pandas开始,原因有很多,我会在结尾和大家说明,现在还是老规矩,我将和大家分享我在学习过程中发现的一些非常不错的资源,没有它们的帮助不论如何我是写不出这些文章的。优秀资源分享在我的Python基础起步系列的最后,我分享了很多优秀资源给大家,这回也不例外,在此我将把写文章期间参考的非常优秀的资源分享给大家,让我们一起进步:综合教程文章 / 视频:Corey Schafer的youtube视频教程,个人认为是最好的视频教程,需要翻墙Py4e,密歇根大学的教程,有详细PPT 可以下载RealPython 由浅入深来学习,我最爱闲逛的网站,我的文章很多是受上面的教程启发DataCamp 很棒的免费教程,付费部分暂不需要Tutorial Point不错的免费教程,个人感觉比w3school强GeeksforGeeks非常棒的综合Python教程平台,我目前碰到的几乎所有问题,都会在上面找到答案Pythonforbeginers非常不错的起步教程,界面简单明了廖雪峰老师的教程,不用多说,名声很大了进阶文档Python设计模式及实用方法Intermediate Python一个很火的python技巧文档在线测试onlinegdb 一个非常好用的在线环境,支持所有语言,做一些简单功能测试的时候很方便,有代码补充提示,可以在线保存新专栏Pandas我想了一段时间,不太确定要先和大家分享OOP编程思想还是Pandas,最后还是决定新建一个Pandas专栏教程,因为现在数据分析非常普遍。相关的工作岗位也很多,同时我自己在工作中应用pandas也比较多,对我而言会更容易一些。从实用性角度讲也是如此,如果你平时的工作涉及到大量的 excel 或者 VBA,那么 pandas 无意是你最好的选择。这次我计划的新专栏会和你常见的不太一样。经过我简单的个人研究,我发现pandas教程遍地都是,但是很多教程的问题如下:一次能讲完的东西,拆分成好几节课没有及时更新,很多停留在2016年或者之前缺少自己的理解和基础模型分享有些收费的课程水分很大我这次会尽我所能,为大家带来干货版本的pandas学习心得,争取用5期达到他人10期的效果,同时会加入一些工作中遇到的,自己创建的,别人教我的小模型等。争取让我的免费分享达到别人收费的标准当然,由于pandas是应用于数据分析的第三方包,分享时会涉及到大量图表,因此我会使用Jupyter Notebook作为环境和编辑器,每期教程后也会和大家分享源代码,这次会正式一些,直接放在 github 里,只希望得到大家的鼓励,并且真正帮助到有需要的人。名词解释:有需要的人:只要你平时用 excel,就是有需要!!!最后想说,多谢很多朋友的鼓励支持,我作为新手注册SegmentFault并开专栏起,已经做好了迎接各种吐槽的准备,然而这种情况并没有出现,除了大家比较善良外,主要原因是没多少人关注 不过慢慢地,在写文章的过程中,我发现也有很多朋友和我一样,是以萌新的身份进入编程领域的。对于这些朋友我想说,你不是一个人在战斗,在学习Python的路上战友越多,就会越轻松,大家互相分享,终会成长,我不否认世上有很多天才,但是大多数时候,一个人的智慧很难和群体抗衡。因此我希望大家可以在我的文章下多多留言,让我在修改错误的同时也能和你一起进步!就这样,让我们下期 Pandas见

February 27, 2019 · 1 min · jiezi

10分钟了解Pandas基础知识

背景在数据分析中pandas举足轻重,学习pandas最好的方法就是看官方文档,以下是根据官方文档10 Minutes to pandas学习记录。(官方标题10分钟,感觉起码得半个小时吧)在pandas中主要有两种数据类型,可以简单的理解为:Series:一维数组DateFrame:二维数组(矩阵)有了大概的概念之后,开始正式认识pandas:首先要引入对应的包:import numpy as npimport pandas as pd新建对象 Object CreationSeries可以通过传入一个list对象来新建Series,其中空值为np.nan:s = pd.Series([1,3,4,np.nan,7,9])sOut[5]: 0 1.01 3.02 4.03 NaN4 7.05 9.0dtype: float64pandas会默认创建一列索引index(上面的0-5)。我们也可以在创建时就指定索引:pd.Series([1,3,4,np.nan,7,9], index=[1,1,2,2,‘a’,4])Out[9]: 1 1.01 3.02 4.02 NaNa 7.04 9.0dtype: float64要注意的是,索引是可以重复的,也可以是字符。DataFrame新建一个DataFrame对象可以有多种方式:通过传入一个numpy的数组、指定一个时间的索引以及一个列名。dates = pd.date_range(‘20190101’, periods=6)datesOut[11]: DatetimeIndex([‘2019-01-01’, ‘2019-01-02’, ‘2019-01-03’, ‘2019-01-04’, ‘2019-01-05’, ‘2019-01-06’], dtype=‘datetime64[ns]’, freq=‘D’)df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list(‘ABCD’))dfOut[18]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-05 -1.122717 -2.789041 -0.791812 -0.1743452019-01-06 0.221597 -0.753038 -1.741256 0.287280通过传入一个dict对象df2 = pd.DataFrame({‘A’:1., ‘B’:pd.Timestamp(‘20190101’), ‘C’:pd.Series(1, index=list(range(4)), dtype=‘float32’), ‘D’:np.array([3]*4, dtype=‘int32’), ‘E’:pd.Categorical([“test”, “tain”, “test”, “train”]), ‘F’:‘foo’})df2Out[27]: A B C D E F0 1.0 2019-01-01 1.0 3 test foo1 1.0 2019-01-01 1.0 3 tain foo2 1.0 2019-01-01 1.0 3 test foo3 1.0 2019-01-01 1.0 3 train foo这里我们指定了不同的类型,可以通过如下查看:df2.dtypesOut[28]: A float64B datetime64[ns]C float32D int32E categoryF objectdtype: object可以看出DataFrame和Series一样,在没有指定索引时,会自动生成一个数字的索引,这在后续的操作中十分重要。查看 Viewing Data查看开头几行或者末尾几行:df.head()Out[30]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-05 -1.122717 -2.789041 -0.791812 -0.174345df.tail(3)Out[31]: A B C D2019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-05 -1.122717 -2.789041 -0.791812 -0.1743452019-01-06 0.221597 -0.753038 -1.741256 0.287280可以通过添加行数参数来输出,默认为输出5行。查看索引和列名df.indexOut[32]: DatetimeIndex([‘2019-01-01’, ‘2019-01-02’, ‘2019-01-03’, ‘2019-01-04’, ‘2019-01-05’, ‘2019-01-06’], dtype=‘datetime64[ns]’, freq=‘D’)df.columnsOut[33]: Index([‘A’, ‘B’, ‘C’, ‘D’], dtype=‘object’)使用DataFrame.to_numpy()转化为numpy数据。需要注意的是由于numpy array类型数据只可包含一种格式,而DataFrame类型数据可包含多种格式,所以在转换过程中,pandas会找到一种可以处理DateFrame中国所有格式的numpy array格式,比如object。这个过程会耗费一定的计算量。df.to_numpy()Out[35]: array([[ 0.67162219, 0.78572584, 0.39243527, 0.87469243], [-2.42070338, -1.11620768, -0.34607048, 0.78594081], [ 1.36442543, -0.94764138, 2.38688005, 0.58537186], [-0.48597971, -1.28145415, 0.35406263, -1.41885798], [-1.12271697, -2.78904135, -0.79181242, -0.17434484], [ 0.22159737, -0.75303807, -1.74125564, 0.28728004]])df2.to_numpy()Out[36]: array([[1.0, Timestamp(‘2019-01-01 00:00:00’), 1.0, 3, ’test’, ‘foo’], [1.0, Timestamp(‘2019-01-01 00:00:00’), 1.0, 3, ’tain’, ‘foo’], [1.0, Timestamp(‘2019-01-01 00:00:00’), 1.0, 3, ’test’, ‘foo’], [1.0, Timestamp(‘2019-01-01 00:00:00’), 1.0, 3, ’train’, ‘foo’]], dtype=object)上面df全部为float类型,所以转换会很快,而df2涉及多种类型转换,最后全部变成了object类型元素。查看数据的简要统计结果df.describe()Out[37]: A B C Dcount 6.000000 6.000000 6.000000 6.000000mean -0.295293 -1.016943 0.042373 0.156680std 1.356107 1.144047 1.396030 0.860725min -2.420703 -2.789041 -1.741256 -1.41885825% -0.963533 -1.240143 -0.680377 -0.05893950% -0.132191 -1.031925 0.003996 0.43632675% 0.559116 -0.801689 0.382842 0.735799max 1.364425 0.785726 2.386880 0.874692转置df.TOut[38]: 2019-01-01 2019-01-02 2019-01-03 2019-01-04 2019-01-05 2019-01-06A 0.671622 -2.420703 1.364425 -0.485980 -1.122717 0.221597B 0.785726 -1.116208 -0.947641 -1.281454 -2.789041 -0.753038C 0.392435 -0.346070 2.386880 0.354063 -0.791812 -1.741256D 0.874692 0.785941 0.585372 -1.418858 -0.174345 0.287280按坐标轴排序,其中axis参数为坐标轴,axis默认为0,即横轴(对行排序),axis=1则为纵轴(对列排序);asceding参数默认为True,即升序排序,ascending=False则为降序排序:df.sort_index(axis=1)Out[44]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-05 -1.122717 -2.789041 -0.791812 -0.1743452019-01-06 0.221597 -0.753038 -1.741256 0.287280df.sort_index(axis=1, ascending=False)Out[45]: D C B A2019-01-01 0.874692 0.392435 0.785726 0.6716222019-01-02 0.785941 -0.346070 -1.116208 -2.4207032019-01-03 0.585372 2.386880 -0.947641 1.3644252019-01-04 -1.418858 0.354063 -1.281454 -0.4859802019-01-05 -0.174345 -0.791812 -2.789041 -1.1227172019-01-06 0.287280 -1.741256 -0.753038 0.221597可见df.sort_index(axis=1)是按列名升序排序,所以看起来没有变化,当设置ascending=False时,列顺序变成了DCBA。按数值排序:df.sort_values(by=‘B’)Out[46]: A B C D2019-01-05 -1.122717 -2.789041 -0.791812 -0.1743452019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-06 0.221597 -0.753038 -1.741256 0.2872802019-01-01 0.671622 0.785726 0.392435 0.874692df.sort_values(by=‘B’, ascending=False)Out[47]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-06 0.221597 -0.753038 -1.741256 0.2872802019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-05 -1.122717 -2.789041 -0.791812 -0.174345筛选 Selection获取某列df[‘A’]Out[49]: 2019-01-01 0.6716222019-01-02 -2.4207032019-01-03 1.3644252019-01-04 -0.4859802019-01-05 -1.1227172019-01-06 0.221597Freq: D, Name: A, dtype: float64type(df.A)Out[52]: pandas.core.series.Series也可直接用df.A,注意这里是大小写敏感的,这时候获取的是一个Series类型数据。选择多行df[0:3]Out[53]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.585372df[‘20190102’:‘20190104’]Out[54]: A B C D2019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-04 -0.485980 -1.281454 0.354063 -1.418858通过一个[]会通过索引对行进行切片,由于前面设置了索引为日期格式,所以可以方便的直接使用日期范围进行筛选。通过标签选择选择某行df.loc[dates[0]]Out[57]: A 0.671622B 0.785726C 0.392435D 0.874692Name: 2019-01-01 00:00:00, dtype: float64选择指定行列的数据df.loc[:, (‘A’, ‘C’)]Out[58]: A C2019-01-01 0.671622 0.3924352019-01-02 -2.420703 -0.3460702019-01-03 1.364425 2.3868802019-01-04 -0.485980 0.3540632019-01-05 -1.122717 -0.7918122019-01-06 0.221597 -1.741256df.loc[‘20190102’:‘20190105’, (‘A’, ‘C’)]Out[62]: A C2019-01-02 -2.420703 -0.3460702019-01-03 1.364425 2.3868802019-01-04 -0.485980 0.3540632019-01-05 -1.122717 -0.791812传入第一个参数是行索引标签范围,第二个是列索引标签,:代表全部。选定某值df.loc[‘20190102’, ‘A’]Out[69]: -2.420703380445092df.at[dates[1], ‘A’]Out[70]: -2.420703380445092可以通过loc[]和at[]两种方式来获取某值,但需要注意的是,由于行索引为datetime类型,使用loc[]方式获取时,可直接使用20190102字符串来代替,而在at[]中,必须传入datetime类型,否则会有报错:df.at[‘20190102’, ‘A’] File “pandas/_libs/index.pyx”, line 81, in pandas._libs.index.IndexEngine.get_value File “pandas/_libs/index.pyx”, line 89, in pandas._libs.index.IndexEngine.get_value File “pandas/_libs/index.pyx”, line 449, in pandas._libs.index.DatetimeEngine.get_loc File “pandas/_libs/index.pyx”, line 455, in pandas._libs.index.DatetimeEngine._date_check_typeKeyError: ‘20190102’通过位置选择选择某行df.iloc[3]Out[71]: A -0.485980B -1.281454C 0.354063D -1.418858Name: 2019-01-04 00:00:00, dtype: float64iloc[]方法的参数,必须是数值。选择指定行列的数据df.iloc[3:5, 0:2]Out[72]: A B2019-01-04 -0.485980 -1.2814542019-01-05 -1.122717 -2.789041df.iloc[:,:]Out[73]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-02 -2.420703 -1.116208 -0.346070 0.7859412019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-04 -0.485980 -1.281454 0.354063 -1.4188582019-01-05 -1.122717 -2.789041 -0.791812 -0.1743452019-01-06 0.221597 -0.753038 -1.741256 0.287280df.iloc[[1, 2, 4], [0, 2]]Out[74]: A C2019-01-02 -2.420703 -0.3460702019-01-03 1.364425 2.3868802019-01-05 -1.122717 -0.791812同loc[],:代表全部。选择某值df.iloc[1, 1]Out[75]: -1.1162076820700824df.iat[1, 1]Out[76]: -1.1162076820700824可以通过iloc[]和iat[]两种方法获取数值。按条件判断选择按某列的数值判断选择df[df.A > 0]Out[77]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-03 1.364425 -0.947641 2.386880 0.5853722019-01-06 0.221597 -0.753038 -1.741256 0.287280筛选出符合要求的数据df[df > 0]Out[78]: A B C D2019-01-01 0.671622 0.785726 0.392435 0.8746922019-01-02 NaN NaN NaN 0.7859412019-01-03 1.364425 NaN 2.386880 0.5853722019-01-04 NaN NaN 0.354063 NaN2019-01-05 NaN NaN NaN NaN2019-01-06 0.221597 NaN NaN 0.287280不符合要求的数据均会被赋值为空NaN。使用isin()方法筛选df2 = df.copy()df2[‘E’] = [‘one’, ‘one’, ’two’, ’three’, ‘four’, ’three’]df2Out[88]: A B C D E2019-01-01 0.671622 0.785726 0.392435 0.874692 one2019-01-02 -2.420703 -1.116208 -0.346070 0.785941 one2019-01-03 1.364425 -0.947641 2.386880 0.585372 two2019-01-04 -0.485980 -1.281454 0.354063 -1.418858 three2019-01-05 -1.122717 -2.789041 -0.791812 -0.174345 four2019-01-06 0.221597 -0.753038 -1.741256 0.287280 threedf2[‘E’].isin([’two’, ‘four’])Out[89]: 2019-01-01 False2019-01-02 False2019-01-03 True2019-01-04 False2019-01-05 True2019-01-06 FalseFreq: D, Name: E, dtype: booldf2[df2[‘E’].isin([’two’, ‘four’])]Out[90]: A B C D E2019-01-03 1.364425 -0.947641 2.386880 0.585372 two2019-01-05 -1.122717 -2.789041 -0.791812 -0.174345 four注意:isin必须严格一致才行,df中的默认数值小数点位数很长,并非显示的5位,为了方便展示,所以新增了E列。直接用原数值,情况如下,可看出[1,1]位置符合要求。df.isin([-1.1162076820700824])Out[95]: A B C D2019-01-01 False False False False2019-01-02 False True False False2019-01-03 False False False False2019-01-04 False False False False2019-01-05 False False False False2019-01-06 False False False False设定值通过指定索引设定列s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range(‘20190102’, periods=6))s1Out[98]: 2019-01-02 12019-01-03 22019-01-04 32019-01-05 42019-01-06 52019-01-07 6Freq: D, dtype: int64df[‘F’]=s1dfOut[101]: A B C D F2019-01-01 0.671622 0.785726 0.392435 0.874692 NaN2019-01-02 -2.420703 -1.116208 -0.346070 0.785941 1.02019-01-03 1.364425 -0.947641 2.386880 0.585372 2.02019-01-04 -0.485980 -1.281454 0.354063 -1.418858 3.02019-01-05 -1.122717 -2.789041 -0.791812 -0.174345 4.02019-01-06 0.221597 -0.753038 -1.741256 0.287280 5.0空值会自动填充为NaN。通过标签设定值df.at[dates[0], ‘A’] = 0dfOut[103]: A B C D F2019-01-01 0.000000 0.785726 0.392435 0.874692 NaN2019-01-02 -2.420703 -1.116208 -0.346070 0.785941 1.02019-01-03 1.364425 -0.947641 2.386880 0.585372 2.02019-01-04 -0.485980 -1.281454 0.354063 -1.418858 3.02019-01-05 -1.122717 -2.789041 -0.791812 -0.174345 4.02019-01-06 0.221597 -0.753038 -1.741256 0.287280 5.0通过为止设定值df.iat[0, 1] = 0dfOut[105]: A B C D F2019-01-01 0.000000 0.000000 0.392435 0.874692 NaN2019-01-02 -2.420703 -1.116208 -0.346070 0.785941 1.02019-01-03 1.364425 -0.947641 2.386880 0.585372 2.02019-01-04 -0.485980 -1.281454 0.354063 -1.418858 3.02019-01-05 -1.122717 -2.789041 -0.791812 -0.174345 4.02019-01-06 0.221597 -0.753038 -1.741256 0.287280 5.0通过NumPy array设定值df.loc[:, ‘D’] = np.array([5] * len(df))dfOut[109]: A B C D F2019-01-01 0.000000 0.000000 0.392435 5 NaN2019-01-02 -2.420703 -1.116208 -0.346070 5 1.02019-01-03 1.364425 -0.947641 2.386880 5 2.02019-01-04 -0.485980 -1.281454 0.354063 5 3.02019-01-05 -1.122717 -2.789041 -0.791812 5 4.02019-01-06 0.221597 -0.753038 -1.741256 5 5.0通过条件判断设定值df2 = df.copy()df2[df2 > 0] = -df2df2Out[112]: A B C D F2019-01-01 0.000000 0.000000 -0.392435 -5 NaN2019-01-02 -2.420703 -1.116208 -0.346070 -5 -1.02019-01-03 -1.364425 -0.947641 -2.386880 -5 -2.02019-01-04 -0.485980 -1.281454 -0.354063 -5 -3.02019-01-05 -1.122717 -2.789041 -0.791812 -5 -4.02019-01-06 -0.221597 -0.753038 -1.741256 -5 -5.0空值处理 Missing Datapandas默认使用np.nan来表示空值,在统计计算中会直接忽略。通过reindex()方法可以新增、修改、删除某坐标轴(行或列)的索引,并返回一个数据的拷贝:df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + [‘E’])df1.loc[dates[0]:dates[1], ‘E’] = 1df1Out[115]: A B C D F E2019-01-01 0.000000 0.000000 0.392435 5 NaN 1.02019-01-02 -2.420703 -1.116208 -0.346070 5 1.0 1.02019-01-03 1.364425 -0.947641 2.386880 5 2.0 NaN2019-01-04 -0.485980 -1.281454 0.354063 5 3.0 NaN删除空值df1.dropna(how=‘any’)Out[116]: A B C D F E2019-01-02 -2.420703 -1.116208 -0.34607 5 1.0 1.0填充空值df1.fillna(value=5)Out[117]: A B C D F E2019-01-01 0.000000 0.000000 0.392435 5 5.0 1.02019-01-02 -2.420703 -1.116208 -0.346070 5 1.0 1.02019-01-03 1.364425 -0.947641 2.386880 5 2.0 5.02019-01-04 -0.485980 -1.281454 0.354063 5 3.0 5.0判断是否为空值pd.isna(df1)Out[118]: A B C D F E2019-01-01 False False False False True False2019-01-02 False False False False False False2019-01-03 False False False False False True2019-01-04 False False False False False True运算 Operations统计注意 所有的统计默认是不包含空值的平均值默认情况是按列求平均值:df.mean()Out[119]: A -0.407230B -1.147897C 0.042373D 5.000000F 3.000000dtype: float64如果需要按行求平均值,需指定轴参数:df.mean(1)Out[120]: 2019-01-01 1.3481092019-01-02 0.4234042019-01-03 1.9607332019-01-04 1.3173262019-01-05 0.8592862019-01-06 1.545461Freq: D, dtype: float64数值移动s = pd.Series([1, 3, 5, np.nan, 6, 8], index=dates)sOut[122]: 2019-01-01 1.02019-01-02 3.02019-01-03 5.02019-01-04 NaN2019-01-05 6.02019-01-06 8.0Freq: D, dtype: float64s = s.shift(2)sOut[125]: 2019-01-01 NaN2019-01-02 NaN2019-01-03 1.02019-01-04 3.02019-01-05 5.02019-01-06 NaNFreq: D, dtype: float64这里将s的值移动两个,那么空出的部分会自动使用NaN填充。不同维度间的运算,pandas会自动扩展维度:df.sub(s, axis=‘index’)Out[128]: A B C D F2019-01-01 NaN NaN NaN NaN NaN2019-01-02 NaN NaN NaN NaN NaN2019-01-03 0.364425 -1.947641 1.386880 4.0 1.02019-01-04 -3.485980 -4.281454 -2.645937 2.0 0.02019-01-05 -6.122717 -7.789041 -5.791812 0.0 -1.02019-01-06 NaN NaN NaN NaN NaN应用通过apply()方法,可以对数据进行逐一操作:累计求和df.apply(np.cumsum)Out[130]: A B C D F2019-01-01 0.000000 0.000000 0.392435 5 NaN2019-01-02 -2.420703 -1.116208 0.046365 10 1.02019-01-03 -1.056278 -2.063849 2.433245 15 3.02019-01-04 -1.542258 -3.345303 2.787307 20 6.02019-01-05 -2.664975 -6.134345 1.995495 25 10.02019-01-06 -2.443377 -6.887383 0.254239 30 15.0这里使用了apply()方法调用np.cumsum方法,也可直接使用df.cumsum():df.cumsum()Out[133]: A B C D F2019-01-01 0.000000 0.000000 0.392435 5.0 NaN2019-01-02 -2.420703 -1.116208 0.046365 10.0 1.02019-01-03 -1.056278 -2.063849 2.433245 15.0 3.02019-01-04 -1.542258 -3.345303 2.787307 20.0 6.02019-01-05 -2.664975 -6.134345 1.995495 25.0 10.02019-01-06 -2.443377 -6.887383 0.254239 30.0 15.0自定义方法通过自定义函数,配合apply()方法,可以实现更多数据处理:df.apply(lambda x: x.max() - x.min())Out[134]: A 3.785129B 2.789041C 4.128136D 0.000000F 4.000000dtype: float64矩阵统计矩阵中每个元素出现的频次:s = pd.Series(np.random.randint(0, 7, size=10))sOut[136]: 0 21 02 43 04 35 36 67 48 69 5dtype: int64s.value_counts()Out[137]: 6 24 23 20 25 12 1dtype: int64String方法所有的Series类型都可以直接调用str的属性方法来对每个对象进行操作。比如转换成大写:s = pd.Series([‘A’, ‘B’, ‘C’, ‘Aaba’, ‘Baca’, np.nan, ‘CABA’, ‘dog’, ‘cat’])s.str.upper()Out[139]: 0 A1 B2 C3 AABA4 BACA5 NaN6 CABA7 DOG8 CATdtype: object分列:s = pd.Series([‘A,b’, ‘c,d’])sOut[142]: 0 A,b1 c,ddtype: objects.str.split(’,’, expand=True)Out[143]: 0 10 A b1 c d其他方法:dir(str)Out[140]: [‘capitalize’, ‘casefold’, ‘center’, ‘count’, ’encode’, ’endswith’, ’expandtabs’, ‘find’, ‘format’, ‘format_map’, ‘index’, ‘isalnum’, ‘isalpha’, ‘isascii’, ‘isdecimal’, ‘isdigit’, ‘isidentifier’, ‘islower’, ‘isnumeric’, ‘isprintable’, ‘isspace’, ‘istitle’, ‘isupper’, ‘join’, ’ljust’, ’lower’, ’lstrip’, ‘maketrans’, ‘partition’, ‘replace’, ‘rfind’, ‘rindex’, ‘rjust’, ‘rpartition’, ‘rsplit’, ‘rstrip’, ‘split’, ‘splitlines’, ‘startswith’, ‘strip’, ‘swapcase’, ’title’, ’translate’, ‘upper’, ‘zfill’]合并 Mergepandas`可以提供很多方法可以快速的合并各种类型的Series、DataFrame以及Panel Object。Concat方法df = pd.DataFrame(np.random.randn(10, 4))dfOut[145]: 0 1 2 30 -0.227408 -0.185674 -0.187919 0.1856851 1.132517 -0.539992 1.156631 -0.0224682 0.214134 -1.283055 -0.862972 0.5189423 0.785903 1.033915 -0.471496 -1.4037624 -0.676717 -0.529971 -1.161988 -1.2650715 0.670126 1.320960 -0.128098 0.7186316 0.589902 0.349386 0.221955 1.7491887 -0.328885 0.607929 -0.973610 -0.9284728 1.724243 -0.661503 -0.374254 0.4092509 1.346625 0.618285 0.528776 -0.628470# break it into piecespieces = [df[:3], df[3:7], df[7:]]piecesOut[147]: [ 0 1 2 3 0 -0.227408 -0.185674 -0.187919 0.185685 1 1.132517 -0.539992 1.156631 -0.022468 2 0.214134 -1.283055 -0.862972 0.518942, 0 1 2 3 3 0.785903 1.033915 -0.471496 -1.403762 4 -0.676717 -0.529971 -1.161988 -1.265071 5 0.670126 1.320960 -0.128098 0.718631 6 0.589902 0.349386 0.221955 1.749188, 0 1 2 3 7 -0.328885 0.607929 -0.973610 -0.928472 8 1.724243 -0.661503 -0.374254 0.409250 9 1.346625 0.618285 0.528776 -0.628470]pd.concat(pieces)Out[148]: 0 1 2 30 -0.227408 -0.185674 -0.187919 0.1856851 1.132517 -0.539992 1.156631 -0.0224682 0.214134 -1.283055 -0.862972 0.5189423 0.785903 1.033915 -0.471496 -1.4037624 -0.676717 -0.529971 -1.161988 -1.2650715 0.670126 1.320960 -0.128098 0.7186316 0.589902 0.349386 0.221955 1.7491887 -0.328885 0.607929 -0.973610 -0.9284728 1.724243 -0.661503 -0.374254 0.4092509 1.346625 0.618285 0.528776 -0.628470Merge方法 这是类似sql的合并方法:left = pd.DataFrame({‘key’: [‘foo’, ‘foo’], ’lval’: [1, 2]})right = pd.DataFrame({‘key’: [‘foo’, ‘foo’], ‘rval’: [4, 5]})leftOut[151]: key lval0 foo 11 foo 2rightOut[152]: key rval0 foo 41 foo 5pd.merge(left, right, on=‘key’)Out[153]: key lval rval0 foo 1 41 foo 1 52 foo 2 43 foo 2 5另一个例子:left = pd.DataFrame({‘key’: [‘foo’, ‘bar’], ’lval’: [1, 2]})right = pd.DataFrame({‘key’: [‘foo’, ‘bar’], ‘rval’: [4, 5]})leftOut[156]: key lval0 foo 11 bar 2rightOut[157]: key rval0 foo 41 bar 5pd.merge(left, right, on=‘key’)Out[158]: key lval rval0 foo 1 41 bar 2 5Append方法在DataFrame中增加行df = pd.DataFrame(np.random.randn(8, 4), columns=[‘A’, ‘B’, ‘C’, ‘D’])dfOut[160]: A B C D0 -0.496709 0.573449 0.076059 0.6852851 0.479253 0.587376 -1.240070 -0.9079102 -0.052609 -0.287786 -1.949402 1.1633233 -0.659489 0.525583 0.820922 -1.3685444 1.270453 -1.813249 0.059915 0.5867035 1.859657 0.564274 -0.198763 -1.7941736 -0.649153 -3.129258 0.063418 -0.7279367 0.862402 -0.800031 -1.954784 -0.028607s = df.iloc[3]sOut[162]: A -0.659489B 0.525583C 0.820922D -1.368544Name: 3, dtype: float64df.append(s, ignore_index=True)Out[163]: A B C D0 -0.496709 0.573449 0.076059 0.6852851 0.479253 0.587376 -1.240070 -0.9079102 -0.052609 -0.287786 -1.949402 1.1633233 -0.659489 0.525583 0.820922 -1.3685444 1.270453 -1.813249 0.059915 0.5867035 1.859657 0.564274 -0.198763 -1.7941736 -0.649153 -3.129258 0.063418 -0.7279367 0.862402 -0.800031 -1.954784 -0.0286078 -0.659489 0.525583 0.820922 -1.368544这里要注意,我们增加了ignore_index=True参数,如果不设置的话,那么增加的新行的index仍然是3,这样在后续的处理中可能有存在问题。具体也需要看情况来处理。df.append(s)Out[164]: A B C D0 -0.496709 0.573449 0.076059 0.6852851 0.479253 0.587376 -1.240070 -0.9079102 -0.052609 -0.287786 -1.949402 1.1633233 -0.659489 0.525583 0.820922 -1.3685444 1.270453 -1.813249 0.059915 0.5867035 1.859657 0.564274 -0.198763 -1.7941736 -0.649153 -3.129258 0.063418 -0.7279367 0.862402 -0.800031 -1.954784 -0.0286073 -0.659489 0.525583 0.820922 -1.368544分组 Grouping一般分组统计有三个步骤:分组:选择需要的数据计算:对每个分组进行计算合并:把分组计算的结果合并为一个数据结构中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)})dfOut[166]: A B C D0 foo one -1.252153 0.1728631 bar one 0.238547 -0.6489802 foo two 0.756975 0.1957663 bar three -0.933405 -0.3200434 foo two -0.310650 -1.3882555 bar two 1.568550 -1.9118176 foo one -0.340290 -2.141259按A列分组并使用sum函数进行计算:df.groupby(‘A’).sum()Out[167]: C DA bar 0.873692 -2.880840foo -1.817027 -5.833961这里由于B列无法应用sum函数,所以直接被忽略了。按A、B列分组并使用sum函数进行计算:df.groupby([‘A’, ‘B’]).sum()Out[168]: C DA B bar one 0.238547 -0.648980 three -0.933405 -0.320043 two 1.568550 -1.911817foo one -1.592443 -1.968396 three -0.670909 -2.673075 two 0.446325 -1.192490这样就有了一个多层index的结果集。整形 Reshaping堆叠 Stackpython的zip函数可以将对象中对应的元素打包成一个个的元组:tuples = list(zip([‘bar’, ‘bar’, ‘baz’, ‘baz’,‘foo’, ‘foo’, ‘qux’, ‘qux’],[‘one’, ’two’, ‘one’, ’two’,‘one’, ’two’, ‘one’, ’two’]))tuplesOut[172]: [(‘bar’, ‘one’), (‘bar’, ’two’), (‘baz’, ‘one’), (‘baz’, ’two’), (‘foo’, ‘one’), (‘foo’, ’two’), (‘qux’, ‘one’), (‘qux’, ’two’)]## 设置两级索引index = pd.MultiIndex.from_tuples(tuples, names=[‘first’, ‘second’])indexOut[174]: MultiIndex(levels=[[‘bar’, ‘baz’, ‘foo’, ‘qux’], [‘one’, ’two’]], codes=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]], names=[‘first’, ‘second’])## 创建DataFramedf = pd.DataFrame(np.random.randn(8, 2), index=index, columns=[‘A’, ‘B’])dfOut[176]: A Bfirst second bar one -0.501215 -0.947993 two -0.828914 0.232167baz one 1.245419 1.006092 two 1.016656 -0.441073foo one 0.479037 -0.500034 two -1.113097 0.591696qux one -0.014760 -0.320735 two -0.648743 1.499899## 选取DataFramedf2 = df[:4]df2Out[179]: A Bfirst second bar one -0.501215 -0.947993 two -0.828914 0.232167baz one 1.245419 1.006092 two 1.016656 -0.441073使用stack()方法,可以通过堆叠的方式将二维数据变成为一维数据:stacked = df2.stack()stackedOut[181]: first second bar one A -0.501215 B -0.947993 two A -0.828914 B 0.232167baz one A 1.245419 B 1.006092 two A 1.016656 B -0.441073dtype: float64对应的逆操作为unstacked()方法:stacked.unstack()Out[182]: A Bfirst second bar one -0.501215 -0.947993 two -0.828914 0.232167baz one 1.245419 1.006092 two 1.016656 -0.441073stacked.unstack(1)Out[183]: second one twofirst bar A -0.501215 -0.828914 B -0.947993 0.232167baz A 1.245419 1.016656 B 1.006092 -0.441073stacked.unstack(0)Out[184]: first bar bazsecond one A -0.501215 1.245419 B -0.947993 1.006092two A -0.828914 1.016656 B 0.232167 -0.441073unstack()默认对最后一层级进行操作,也可通过输入参数指定。表格转置df = pd.DataFrame({‘A’: [‘one’, ‘one’, ’two’, ’three’] * 3,‘B’: [‘A’, ‘B’, ‘C’] * 4,‘C’: [‘foo’, ‘foo’, ‘foo’, ‘bar’, ‘bar’, ‘bar’] * 2,‘D’: np.random.randn(12),‘E’: np.random.randn(12)})dfOut[190]: A B C D E0 one A foo -0.933264 -2.3874901 one B foo -0.288101 0.0232142 two C foo 0.594490 0.4185053 three A bar 0.450683 1.9396234 one B bar 0.243897 -0.9657835 one C bar -0.705494 -0.0782836 two A foo 1.560352 0.4199077 three B foo 0.199453 0.9987118 one C foo 1.426861 -1.1082979 one A bar -0.570951 -0.02256010 two B bar -0.350937 -1.76780411 three C bar 0.983465 0.065792通过pivot_table()方法可以很方便的进行行列的转换:pd.pivot_table(df, values=‘D’, index=[‘A’, ‘B’], columns=[‘C’])Out[191]: C bar fooA B one A -0.570951 -0.933264 B 0.243897 -0.288101 C -0.705494 1.426861three A 0.450683 NaN B NaN 0.199453 C 0.983465 NaNtwo A NaN 1.560352 B -0.350937 NaN C NaN 0.594490转换中,涉及到空值部分会自动填充为NaN。时间序列 Time Seriespandas的在时序转换方面十分强大,可以很方便的进行各种转换。时间间隔调整rng = pd.date_range(‘1/1/2019’, periods=100, freq=‘S’)rng[:5]Out[214]: DatetimeIndex([‘2019-01-01 00:00:00’, ‘2019-01-01 00:00:01’, ‘2019-01-01 00:00:02’, ‘2019-01-01 00:00:03’, ‘2019-01-01 00:00:04’], dtype=‘datetime64[ns]’, freq=‘S’)ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)ts.head(5)Out[216]: 2019-01-01 00:00:00 2452019-01-01 00:00:01 3472019-01-01 00:00:02 1132019-01-01 00:00:03 1962019-01-01 00:00:04 131Freq: S, dtype: int64## 按10s间隔进行重新采样ts1 = ts.resample(‘10S’)ts1Out[209]: DatetimeIndexResampler [freq=<10 * Seconds>, axis=0, closed=left, label=left, convention=start, base=0]## 用求平均的方式进行数据整合 ts1.mean()Out[218]: 2019-01-01 00:00:00 174.02019-01-01 00:00:10 278.52019-01-01 00:00:20 281.82019-01-01 00:00:30 337.22019-01-01 00:00:40 221.02019-01-01 00:00:50 277.12019-01-01 00:01:00 171.02019-01-01 00:01:10 321.02019-01-01 00:01:20 318.62019-01-01 00:01:30 302.6Freq: 10S, dtype: float64## 用求和的方式进行数据整合 ts1.sum()Out[219]: 2019-01-01 00:00:00 17402019-01-01 00:00:10 27852019-01-01 00:00:20 28182019-01-01 00:00:30 33722019-01-01 00:00:40 22102019-01-01 00:00:50 27712019-01-01 00:01:00 17102019-01-01 00:01:10 32102019-01-01 00:01:20 31862019-01-01 00:01:30 3026Freq: 10S, dtype: int64这里先通过resample进行重采样,在指定sum()或者mean()等方式来指定冲采样的处理方式。显示时区:rng = pd.date_range(‘1/1/2019 00:00’, periods=5, freq=‘D’)rngOut[221]: DatetimeIndex([‘2019-01-01’, ‘2019-01-02’, ‘2019-01-03’, ‘2019-01-04’, ‘2019-01-05’], dtype=‘datetime64[ns]’, freq=‘D’)ts = pd.Series(np.random.randn(len(rng)), rng)tsOut[223]: 2019-01-01 -2.3276862019-01-02 1.5278722019-01-03 0.0639822019-01-04 -0.2135722019-01-05 -0.014856Freq: D, dtype: float64ts_utc = ts.tz_localize(‘UTC’)ts_utcOut[225]: 2019-01-01 00:00:00+00:00 -2.3276862019-01-02 00:00:00+00:00 1.5278722019-01-03 00:00:00+00:00 0.0639822019-01-04 00:00:00+00:00 -0.2135722019-01-05 00:00:00+00:00 -0.014856Freq: D, dtype: float64转换时区:ts_utc.tz_convert(‘US/Eastern’)Out[226]: 2018-12-31 19:00:00-05:00 -2.3276862019-01-01 19:00:00-05:00 1.5278722019-01-02 19:00:00-05:00 0.0639822019-01-03 19:00:00-05:00 -0.2135722019-01-04 19:00:00-05:00 -0.014856Freq: D, dtype: float64时间格式转换rng = pd.date_range(‘1/1/2019’, periods=5, freq=‘M’)ts = pd.Series(np.random.randn(len(rng)), index=rng)tsOut[230]: 2019-01-31 0.1971342019-02-28 0.5690822019-03-31 -0.3221412019-04-30 0.0057782019-05-31 -0.082306Freq: M, dtype: float64ps = ts.to_period()psOut[232]: 2019-01 0.1971342019-02 0.5690822019-03 -0.3221412019-04 0.0057782019-05 -0.082306Freq: M, dtype: float64ps.to_timestamp()Out[233]: 2019-01-01 0.1971342019-02-01 0.5690822019-03-01 -0.3221412019-04-01 0.0057782019-05-01 -0.082306Freq: MS, dtype: float64在是时间段和时间转换过程中,有一些很方便的算术方法可以使用,比如我们转换如下两个频率:1、按季度划分,且每个年的最后一个月是11月。2、按季度划分,每个月开始为频率一中下一个月的早上9点。prng = pd.period_range(‘2018Q1’, ‘2019Q4’, freq=‘Q-NOV’)prngOut[243]: PeriodIndex([‘2018Q1’, ‘2018Q2’, ‘2018Q3’, ‘2018Q4’, ‘2019Q1’, ‘2019Q2’, ‘2019Q3’, ‘2019Q4’], dtype=‘period[Q-NOV]’, freq=‘Q-NOV’)ts = pd.Series(np.random.randn(len(prng)), prng)tsOut[245]: 2018Q1 -0.1126922018Q2 -0.5073042018Q3 -0.3248462018Q4 0.5496712019Q1 -0.8977322019Q2 1.1300702019Q3 -0.3998142019Q4 0.830488Freq: Q-NOV, dtype: float64ts.index = (prng.asfreq(‘M’, ’e’) + 1).asfreq(‘H’, ’s’) + 9tsOut[247]: 2018-03-01 09:00 -0.1126922018-06-01 09:00 -0.5073042018-09-01 09:00 -0.3248462018-12-01 09:00 0.5496712019-03-01 09:00 -0.8977322019-06-01 09:00 1.1300702019-09-01 09:00 -0.3998142019-12-01 09:00 0.830488Freq: H, dtype: float64注意:这个例子有点怪。可以这样理解,我们先将prng直接转换为按小时显示:prng.asfreq(‘H’, ’end’) Out[253]: PeriodIndex([‘2018-02-28 23:00’, ‘2018-05-31 23:00’, ‘2018-08-31 23:00’, ‘2018-11-30 23:00’, ‘2019-02-28 23:00’, ‘2019-05-31 23:00’, ‘2019-08-31 23:00’, ‘2019-11-30 23:00’], dtype=‘period[H]’, freq=‘H’)我们要把时间转换为下一个月的早上9点,所以先转换为按月显示,并每个月加1(即下个月),然后按小时显示并加9(早上9点)。另外例子中s参数是start的简写,e参数是end的简写,Q-NOV即表示按季度,且每年的NOV是最后一个月。更多了freq简称可以参考:http://pandas.pydata.org/pand…asfreq()方法介绍可参考:http://pandas.pydata.org/pand…分类目录类型 Categoricals关于Categories类型介绍可以参考:http://pandas.pydata.org/pand…类型转换:astype(‘category’)df = pd.DataFrame({“id”: [1, 2, 3, 4, 5, 6],“raw_grade”: [‘a’, ‘b’, ‘b’, ‘a’, ‘a’, ’e’]})dfOut[255]: id raw_grade0 1 a1 2 b2 3 b3 4 a4 5 a5 6 edf[‘grade’] = df[‘raw_grade’].astype(‘category’)df[‘grade’]Out[257]: 0 a1 b2 b3 a4 a5 eName: grade, dtype: categoryCategories (3, object): [a, b, e]重命名分类:catdf[“grade”].cat.categories = [“very good”, “good”, “very bad”]df[‘grade’]Out[269]: 0 very good1 good2 good3 very good4 very good5 very badName: grade, dtype: categoryCategories (3, object): [very good, good, very bad]重分类:df[‘grade’] = df[‘grade’].cat.set_categories([“very bad”, “bad”, “medium”,“good”, “very good”])df[‘grade’]Out[271]: 0 very good1 good2 good3 very good4 very good5 very badName: grade, dtype: categoryCategories (5, object): [very bad, bad, medium, good, very good]排列df.sort_values(by=“grade”)Out[272]: id raw_grade grade5 6 e very bad1 2 b good2 3 b good0 1 a very good3 4 a very good4 5 a very good分组df.groupby(“grade”).size()Out[273]: gradevery bad 1bad 0medium 0good 2very good 3dtype: int64画图 PlottingSeriests = pd.Series(np.random.randn(1000),index=pd.date_range(‘1/1/2000’, periods=1000))ts = pd.Series(np.random.randn(1000),index=pd.date_range(‘1/1/2019’, periods=1000))ts = ts.cumsum()ts.plot()Out[277]: <matplotlib.axes._subplots.AxesSubplot at 0x1135bcc50>import matplotlib.pyplot as pltplt.show()DataFrame画图使用plot可以把所有的列都通过标签的形式展示出来:df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,columns=[‘A’, ‘B’, ‘C’, ‘D’])df = df.cumsum()plt.figure()Out[282]: <Figure size 640x480 with 0 Axes>df.plot()Out[283]: <matplotlib.axes._subplots.AxesSubplot at 0x11587e4e0>plt.legend(loc=‘best’)导入导出数据 Getting Data In/OutCSV写入:df.to_csv(‘foo.csv’)读取:pd.read_csv(‘foo.csv’)HDF5写入:df.to_hdf(‘foo.h5’, ‘df’)读取:pd.read_hdf(‘foo.h5’, ‘df’)Excel写入:df.to_excel(‘foo.xlsx’, sheet_name=‘Sheet1’)读取:pd.read_excel(‘foo.xlsx’, ‘Sheet1’, index_col=None, na_values=[‘NA’])异常处理 Gotchas如果有一些异常情况比如:>>> if pd.Series([False, True, False]):… print(“I was true”)Traceback …ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().可以参考如下链接:http://pandas.pydata.org/pand…http://pandas.pydata.org/pand… ...

February 25, 2019 · 13 min · jiezi

pandas 修改 DataFrame 列名

本文参考自:pandas 修改 DataFrame 列名 原博客针对每个DataFrame.columns中的元素做相同的修改操作而拙作是对每个元素做不同操作的生搬硬套, 请大家不吝赐教提出问题存在一个名为dataset的DataFrame>>> dataset.columnsIndex([‘age’, ‘job’, ‘marital’, ’education’, ‘default’, ‘housing’, ’loan’, ‘contact’, ‘month’, ‘day_of_week’, ‘duration’, ‘campaign’, ‘pdays’, ‘previous’, ‘poutcome’, ’emp.var.rate’, ‘cons.price.idx’, ‘cons.conf.idx’, ’euribor3m’, ’nr.employed’, ‘y’], dtype=‘object’)现在, 我要将其columns名字改为:>>> new_columnsIndex([‘age_0’, ‘job_1’, ‘marital_2’, ’education_3’, ‘default_4’, ‘housing_5’, ’loan_6’, ‘contact_7’, ‘month_8’, ‘day_of_week_9’, ‘duration_10’, ‘campaign_11’, ‘pdays_12’, ‘previous_13’, ‘poutcome_14’, ’emp.var.rate_15’, ‘cons.price.idx_16’, ‘cons.conf.idx_17’, ’euribor3m_18’, ’nr.employed_19’, ‘y_20’], dtype=‘object’)该如何操作?解决一.通过DataFrame.columns类的自身属性修改:1.无脑赋值直接修改>>> # 先解决new_columns的推导问题>>> # 列表推导>>> new_columns_list = [column_str+’’+str(i) for i ,column_str in enumerate(dataset.columns)]>>> # 类型转换>>> new_columns = pd.core.indexes.base.Index(new_columns_list)>>> dataset.columns = new_columns2.通过.map(mapper, na_action=None)函数来修改>>> # 注:mapper 多运用 lambda 表达式>>> # 但我似乎没有找到在 lambda 表达式中改变两个值的方法>>> # 所以只能蹩脚地用一个全局变量i, 和映射函数mapper()>>> # 希望大家能帮我找到方法>>> i = 0>>> def mapper(x): # 映射函数即 mapper global i x += ‘’ + str(i) i += 1 return x>>> dataset.columns.map(mapper)3.参考博客用到了DataFrame.columns.str对象用help(DataFrame.columns.str)翻遍了文档,也没能找到可以被我拿来套用的方法, 想着抽时间把这段文档翻译一下二.通过DataFrame.rename()函数来修改1.暴力字典法(好处:可以只修改特定的列)>>> # 此处先用字典推导法>>> new_dict = { key:key+’’+str(i) for i, key in enumerate(dataset.columns) }>>> dataset.rename(columns=new_dict, inplace=True)2.映射修改法>>> # 原博文依然用到了 lambda 表达式>>> # 我就再生搬硬套一次, 把上面的复制过来>>> # 蹩脚地用一个全局变量i, 和映射函数mapper()>>> i = 0>>> def mapper(x): # 映射函数即 mapper global i x += ‘’ + str(i) i += 1 return xdataset.rename(columns=mapper, inplace=True)写在最后十分欢迎大家直接修改拙作或提出建议!!! ...

February 21, 2019 · 1 min · jiezi

Python Pandas读取修改excel操作攻略

环境:python 3.6.8以某米赛尔号举个例子吧:>>> pd.read_excel(‘1.xlsx’, sheet_name=‘Sheet2’) 名字 等级 属性1 属性2 天赋0 四九幻曦 100 自然 None 211 圣甲狂战 100 战斗 None 02 时空界皇 100 光 次元 27我们在这里使用了pd.read_excel()函数来读取excel,来看一下read_excel()这个方法的API,这里只截选一部分经常使用的参数:pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None)io:很明显, 是excel文件的路径+名字字符串(有中文的话python2的老铁需要使用decode()来解码成unicode字符串) 例如:>>> pd.read_excel(‘例子’.decode(‘utf-8))sheet_name:返回指定的sheet如果将sheet_name指定为None,则返回全表如果需要返回多个表, 可以将sheet_name指定为一个列表, 例如[‘sheet1’, ‘sheet2’]可以根据sheet的名字字符串或索引来值指定所要选取的sheet>>> # 如:>>> pd.read_excel(‘1.xlsx’, sheet_name=0)>>> pd.read_excel(‘1.xlsx’, sheet_name=‘Sheet1’)>>> # 返回的是相同的 DataFrameheader:指定数据表的表头,默认值为0, 即将第一行作为表头usecols:读取指定的列, 也可以通过名字或索引值>>> # 如:>>> pd.read_excel(‘1.xlsx’, sheet_name=1, usecols=[‘等级’, ‘属性1’])>>> pd.read_excel(‘1.xlsx’, sheet_name=1, usecols=[1,2])>>> # 返回的是相同的 DataFrame直到某一天泰格尔升了一级, 可以这样改一下, 当然用.iloc或.loc对象都可以>>> # 读取文件>>> data = pd.read_excel(“1.xlsx”, sheet_name=“Sheet1”)>>> # 找到 等级 这一列,再在这一列中进行比较>>> data[‘等级’][data[‘名字’] == ‘泰格尔’] += 1>>> print(data)LOOK!他升级了!!>>> data 名字 等级 属性1 属性2 天赋0 艾欧里娅 100 自然 冰 291 泰格尔 81 电 战斗 162 布鲁克克 100 水 None 28现在我们将它保存data.to_excel(‘1.xlsx’, sheet_name=‘Sheet1’, index=False, header=True)index:默认为True, 是否加行索引, 直接上图吧!左为False, 右为Trueheader:默认为True, 是否加列标, 上图吧!左为False, 右为True而io, sheet_name参数用法同函数pd.read_excel()如果我们多捕捉几只或者多加几种属性怎么办呢?这里给出参考:新增列数据:data[‘列名称’] = [值1, 值2, ……]>>> data[‘特性’] = [‘瞬杀’, ‘None’, ‘炎火’]>>> data 名字 等级 属性1 属性2 天赋 特性0 艾欧里娅 100 自然 冰 29 瞬杀1 泰格尔 80 电 战斗 16 None2 布鲁克克 100 水 None 28 炎火新增行数据,这里行的num为excel中自动给行加的id数值data.loc[行的num] = [值1, 值2, …], (注意与.iloc的区别)>>> data.loc[3] = [‘小火猴’, 1, ‘火’, ‘None’, 31, ‘None’]>>> data 名字 等级 属性1 属性2 天赋 特性0 艾欧里娅 100 自然 冰 29 瞬杀1 泰格尔 80 电 战斗 16 None2 布鲁克克 100 水 None 28 炎火3 小火猴 1 火 None 31 None说完了增加一行或一列,那怎样删除一行或一列呢?可以使用.drop()函数>>> # 删除列, 需要指定axis为1,当删除行时,axis为0>>> data = data.drop(‘属性1’, axis=1) # 删除属性1列>>> data 名字 等级 属性2 天赋 特性0 艾欧里娅 100 冰 29 瞬杀1 泰格尔 80 战斗 16 None2 布鲁克克 100 None 28 炎火3 小火猴 1 None 31 None>>> # 删除第3,4行,这里下表以0开始,并且标题行不算在类, axis用法同上>>> data = data.drop([2, 3], axis=0)>>> data 名字 等级 属性2 天赋 特性0 艾欧里娅 100 冰 29 瞬杀1 泰格尔 80 战斗 16 None>>> # 保存>>> data.to_excel(‘2.xlsx’, sheet_name=‘Sheet1’, index=False, header=True)大家具体可以参考官网提供的API:http://pandas.pydata.org/pand… ...

February 17, 2019 · 2 min · jiezi

还在抱怨pandas运行速度慢?这几个方法会颠覆你的看法

作者:xiaoyu微信公众号:Python数据科学知乎:python数据分析师前言当大家谈到数据分析时,提及最多的语言就是Python和SQL。Python之所以适合数据分析,是因为它有很多第三方强大的库来协助,pandas就是其中之一。pandas的文档中是这样描述的:“快速,灵活,富有表现力的数据结构,旨在使”关系“或”标记“数据的使用既简单又直观。”我们知道pandas的两个主要数据结构:dataframe和series,我们对数据的一些操作都是基于这两个数据结构的。但在实际的使用中,我们可能很多时候会感觉运行一些数据结构的操作会异常的慢。一个操作慢几秒可能看不出来什么,但是一整个项目中很多个操作加起来会让整个开发工作效率变得很低。有的朋友抱怨pandas简直太慢了,其实对于pandas的一些操作也是有一定技巧的。pandas是基于numpy库的数组结构上构建的,并且它的很多操作都是(通过numpy或者pandas自身由Cpython实现并编译成C的扩展模块)在C语言中实现的。因此,如果正确使用pandas的话,它的运行速度应该是非常快的。本篇将要介绍几种pandas中常用到的方法,对于这些方法使用存在哪些需要注意的问题,以及如何对它们进行速度提升。将datetime数据与时间序列一起使用的优点进行批量计算的最有效途径通过HDFStore存储数据节省时间使用Datetime数据节省时间我们来看一个例子。>>> import pandas as pd>>> pd.version‘0.23.1’# 导入数据集>>> df = pd.read_csv(‘demand_profile.csv’)>>> df.head() date_time energy_kwh0 1/1/13 0:00 0.5861 1/1/13 1:00 0.5802 1/1/13 2:00 0.5723 1/1/13 3:00 0.5964 1/1/13 4:00 0.592从运行上面代码得到的结果来看,好像没有什么问题。但实际上pandas和numpy都有一个dtypes 的概念。如果没有特殊声明,那么date_time将会使用一个 object 的dtype类型,如下面代码所示:>>> df.dtypesdate_time objectenergy_kwh float64dtype: object>>> type(df.iat[0, 0])strobject 类型像一个大的容器,不仅仅可以承载 str,也可以包含那些不能很好地融进一个数据类型的任何特征列。而如果我们将日期作为 str 类型就会极大的影响效率。因此,对于时间序列的数据而言,我们需要让上面的date_time列格式化为datetime对象数组(pandas称之为时间戳)。pandas在这里操作非常简单,操作如下:>>> df[‘date_time’] = pd.to_datetime(df[‘date_time’])>>> df[‘date_time’].dtypedatetime64[ns]我们来运行一下这个df看看转化后的效果是什么样的。>>> df.head() date_time energy_kwh0 2013-01-01 00:00:00 0.5861 2013-01-01 01:00:00 0.5802 2013-01-01 02:00:00 0.5723 2013-01-01 03:00:00 0.5964 2013-01-01 04:00:00 0.592date_time的格式已经自动转化了,但这还没完,在这个基础上,我们还是可以继续提高运行速度的。如何提速呢?为了更好的对比,我们首先通过 timeit 装饰器来测试一下上面代码的转化时间。>>> @timeit(repeat=3, number=10)… def convert(df, column_name):… return pd.to_datetime(df[column_name])>>> df[‘date_time’] = convert(df, ‘date_time’)Best of 3 trials with 10 function calls per trial:Function convert ran in average of 1.610 seconds.1.61s,看上去挺快,但其实可以更快,我们来看一下下面的方法。>>> @timeit(repeat=3, number=100)>>> def convert_with_format(df, column_name):… return pd.to_datetime(df[column_name],… format=’%d/%m/%y %H:%M’)Best of 3 trials with 100 function calls per trial:Function convert_with_format ran in average of 0.032 seconds.结果只有0.032s,快了将近50倍。原因是:我们设置了转化的格式format。由于在CSV中的datetimes并不是 ISO 8601 格式的,如果不进行设置的话,那么pandas将使用 dateutil 包把每个字符串str转化成date日期。相反,如果原始数据datetime已经是 ISO 8601 格式了,那么pandas就可以立即使用最快速的方法来解析日期。这也就是为什么提前设置好格式format可以提升这么多。pandas数据的循环操作仍然基于上面的数据,我们想添加一个新的特征,但这个新的特征是基于一些时间条件的,根据时长(小时)而变化,如下:因此,按照我们正常的做法就是使用apply方法写一个函数,函数里面写好时间条件的逻辑代码。def apply_tariff(kwh, hour): “““计算每个小时的电费””” if 0 <= hour < 7: rate = 12 elif 7 <= hour < 17: rate = 20 elif 17 <= hour < 24: rate = 28 else: raise ValueError(f’Invalid hour: {hour}’) return rate * kwh然后使用for循环来遍历df,根据apply函数逻辑添加新的特征,如下:>>> # 不赞同这种操作>>> @timeit(repeat=3, number=100)… def apply_tariff_loop(df):… “““Calculate costs in loop. Modifies df inplace.”””… energy_cost_list = []… for i in range(len(df)):… # 获取用电量和时间(小时)… energy_used = df.iloc[i][’energy_kwh’]… hour = df.iloc[i][‘date_time’].hour… energy_cost = apply_tariff(energy_used, hour)… energy_cost_list.append(energy_cost)… df[‘cost_cents’] = energy_cost_list… >>> apply_tariff_loop(df)Best of 3 trials with 100 function calls per trial:Function apply_tariff_loop ran in average of 3.152 seconds.对于那些写Pythonic风格的人来说,这个设计看起来很自然。然而,这个循环将会严重影响效率,也是不赞同这么做。原因有几个:首先,它需要初始化一个将记录输出的列表。其次,它使用不透明对象范围(0,len(df))循环,然后在应用apply_tariff()之后,它必须将结果附加到用于创建新DataFrame列的列表中。它还使用df.iloc [i] [‘date_time’]执行所谓的链式索引,这通常会导致意外的结果。但这种方法的最大问题是计算的时间成本。对于8760行数据,此循环花费了3秒钟。接下来,你将看到一些改进的Pandas结构迭代解决方案。使用itertuples() 和iterrows() 循环那么推荐做法是什么样的呢?实际上可以通过pandas引入itertuples和iterrows方法可以使效率更快。这些都是一次产生一行的生成器方法,类似scrapy中使用的yield用法。.itertuples为每一行产生一个namedtuple,并且行的索引值作为元组的第一个元素。nametuple是Python的collections模块中的一种数据结构,其行为类似于Python元组,但具有可通过属性查找访问的字段。.iterrows为DataFrame中的每一行产生(index,series)这样的元组。虽然.itertuples往往会更快一些,但是在这个例子中使用.iterrows,我们看看这使用iterrows后效果如何。>>> @timeit(repeat=3, number=100)… def apply_tariff_iterrows(df):… energy_cost_list = []… for index, row in df.iterrows():… # 获取用电量和时间(小时)… energy_used = row[’energy_kwh’]… hour = row[‘date_time’].hour… # 添加cost列表… energy_cost = apply_tariff(energy_used, hour)… energy_cost_list.append(energy_cost)… df[‘cost_cents’] = energy_cost_list…>>> apply_tariff_iterrows(df)Best of 3 trials with 100 function calls per trial:Function apply_tariff_iterrows ran in average of 0.713 seconds.语法方面:这样的语法更明确,并且行值引用中的混乱更少,因此它更具可读性。在时间收益方面:快了近5倍! 但是,还有更多的改进空间。我们仍然在使用某种形式的Python for循环,这意味着每个函数调用都是在Python中完成的,理想情况是它可以用Pandas内部架构中内置的更快的语言完成。Pandas的 .apply()方法我们可以使用.apply方法而不是.iterrows进一步改进此操作。Pandas的.apply方法接受函数(callables)并沿DataFrame的轴(所有行或所有列)应用它们。在此示例中,lambda函数将帮助你将两列数据传递给apply_tariff():>>> @timeit(repeat=3, number=100)… def apply_tariff_withapply(df):… df[‘cost_cents’] = df.apply(… lambda row: apply_tariff(… kwh=row[’energy_kwh’],… hour=row[‘date_time’].hour),… axis=1)…>>> apply_tariff_withapply(df)Best of 3 trials with 100 function calls per trial:Function apply_tariff_withapply ran in average of 0.272 seconds..apply的语法优点很明显,行数少,代码可读性高。在这种情况下,所花费的时间大约是.iterrows方法的一半。但是,这还不是“非常快”。一个原因是.apply()将在内部尝试循环遍历Cython迭代器。但是在这种情况下,传递的lambda不是可以在Cython中处理的东西,因此它在Python中调用,因此并不是那么快。如果你使用.apply()获取10年的小时数据,那么你将需要大约15分钟的处理时间。如果这个计算只是大型模型的一小部分,那么你真的应该加快速度。这也就是矢量化操作派上用场的地方。矢量化操作:使用.isin()选择数据什么是矢量化操作?如果你不基于一些条件,而是可以在一行代码中将所有电力消耗数据应用于该价格(df [’energy_kwh’] * 28),类似这种。这个特定的操作就是矢量化操作的一个例子,它是在Pandas中执行的最快方法。但是如何将条件计算应用为Pandas中的矢量化运算?一个技巧是根据你的条件选择和分组DataFrame,然后对每个选定的组应用矢量化操作。 在下一个示例中,你将看到如何使用Pandas的.isin()方法选择行,然后在向量化操作中实现上面新特征的添加。在执行此操作之前,如果将date_time列设置为DataFrame的索引,则会使事情更方便:df.set_index(‘date_time’, inplace=True)@timeit(repeat=3, number=100)def apply_tariff_isin(df):# 定义小时范围Boolean数组 peak_hours = df.index.hour.isin(range(17, 24)) shoulder_hours = df.index.hour.isin(range(7, 17)) off_peak_hours = df.index.hour.isin(range(0, 7)) # 使用上面的定义 df.loc[peak_hours, ‘cost_cents’] = df.loc[peak_hours, ’energy_kwh’] * 28 df.loc[shoulder_hours,‘cost_cents’] = df.loc[shoulder_hours, ’energy_kwh’] * 20 df.loc[off_peak_hours,‘cost_cents’] = df.loc[off_peak_hours, ’energy_kwh’] * 12我们来看一下结果如何。>>> apply_tariff_isin(df)Best of 3 trials with 100 function calls per trial:Function apply_tariff_isin ran in average of 0.010 seconds.为了了解刚才代码中发生的情况,我们需要知道.isin()方法返回的是一个布尔值数组,如下所示:[False, False, False, …, True, True, True]这些值标识哪些DataFrame索引(datetimes)落在指定的小时范围内。然后,当你将这些布尔数组传递给DataFrame的.loc索引器时,你将获得一个仅包含与这些小时匹配的行的DataFrame切片。在那之后,仅仅是将切片乘以适当的费率,这是一种快速的矢量化操作。这与我们上面的循环操作相比如何?首先,你可能会注意到不再需要apply_tariff(),因为所有条件逻辑都应用于行的选择。因此,你必须编写的代码行和调用的Python代码会大大减少。处理时间怎么样?比不是Pythonic的循环快315倍,比.iterrows快71倍,比.apply快27倍。还可以做的更好吗?在apply_tariff_isin中,我们仍然可以通过调用df.loc和df.index.hour.isin三次来进行一些“手动工作”。如果我们有更精细的时隙范围,你可能会争辩说这个解决方案是不可扩展的。幸运的是,在这种情况下,你可以使用Pandas的pd.cut() 函数以编程方式执行更多操作:@timeit(repeat=3, number=100)def apply_tariff_cut(df): cents_per_kwh = pd.cut(x=df.index.hour, bins=[0, 7, 17, 24], include_lowest=True, labels=[12, 20, 28]).astype(int) df[‘cost_cents’] = cents_per_kwh * df[’energy_kwh’]让我们看看这里发生了什么。pd.cut() 根据每小时所属的bin应用一组标签(costs)。注意include_lowest参数表示第一个间隔是否应该是包含左边的(您希望在组中包含时间= 0)。这是一种完全矢量化的方式来获得我们的预期结果,它在时间方面是最快的:>>> apply_tariff_cut(df)Best of 3 trials with 100 function calls per trial:Function apply_tariff_cut ran in average of 0.003 seconds. 到目前为止,时间上基本快达到极限了,只需要花费不到一秒的时间来处理完整的10年的小时数据集。但是,最后一个选项是使用 NumPy 函数来操作每个DataFrame的底层NumPy数组,然后将结果集成回Pandas数据结构中。使用Numpy继续加速使用Pandas时不应忘记的一点是Pandas Series和DataFrames是在NumPy库之上设计的。这为你提供了更多的计算灵活性,因为Pandas可以与NumPy阵列和操作无缝衔接。下面,我们将使用NumPy的 digitize() 函数。它类似于Pandas的cut(),因为数据将被分箱,但这次它将由一个索引数组表示,这些索引表示每小时所属的bin。然后将这些索引应用于价格数组:@timeit(repeat=3, number=100)def apply_tariff_digitize(df): prices = np.array([12, 20, 28]) bins = np.digitize(df.index.hour.values, bins=[7, 17, 24]) df[‘cost_cents’] = prices[bins] * df[’energy_kwh’].values与cut函数一样,这种语法非常简洁易读。但它在速度方面有何比较?让我们来看看:>>> apply_tariff_digitize(df)Best of 3 trials with 100 function calls per trial:Function apply_tariff_digitize ran in average of 0.002 seconds.在这一点上,仍然有性能提升,但它本质上变得更加边缘化。使用Pandas,它可以帮助维持“层次结构”,如果你愿意,可以像在此处一样进行批量计算,这些通常排名从最快到最慢(最灵活到最不灵活):1. 使用向量化操作:没有for循环的Pandas方法和函数。2. 将.apply方法:与可调用方法一起使用。3. 使用.itertuples:从Python的集合模块迭代DataFrame行作为namedTuples。4. 使用.iterrows:迭代DataFrame行作为(index,Series)对。虽然Pandas系列是一种灵活的数据结构,但将每一行构建到一个系列中然后访问它可能会很昂贵。5. 使用“element-by-element”循环:使用df.loc或df.iloc一次更新一个单元格或行。使用HDFStore防止重新处理现在你已经了解了Pandas中的加速数据流程,接着让我们探讨如何避免与最近集成到Pandas中的HDFStore一起重新处理时间。通常,在构建复杂数据模型时,可以方便地对数据进行一些预处理。例如,如果您有10年的分钟频率耗电量数据,即使你指定格式参数,只需将日期和时间转换为日期时间可能需要20分钟。你真的只想做一次,而不是每次运行你的模型,进行测试或分析。你可以在此处执行的一项非常有用的操作是预处理,然后将数据存储在已处理的表单中,以便在需要时使用。但是,如何以正确的格式存储数据而无需再次重新处理?如果你要另存为CSV,则只会丢失datetimes对象,并且在再次访问时必须重新处理它。Pandas有一个内置的解决方案,它使用 HDF5,这是一种专门用于存储表格数据阵列的高性能存储格式。 Pandas的 HDFStore 类允许你将DataFrame存储在HDF5文件中,以便可以有效地访问它,同时仍保留列类型和其他元数据。它是一个类似字典的类,因此您可以像读取Python dict对象一样进行读写。以下是将预处理电力消耗DataFrame df存储在HDF5文件中的方法:# 创建储存对象,并存为 processed_datadata_store = pd.HDFStore(‘processed_data.h5’)# 将 DataFrame 放进对象中,并设置 key 为 preprocessed_dfdata_store[‘preprocessed_df’] = dfdata_store.close()现在,你可以关闭计算机并休息一下。等你回来的时候,你处理的数据将在你需要时为你所用,而无需再次加工。以下是如何从HDF5文件访问数据,并保留数据类型:# 获取数据储存对象data_store = pd.HDFStore(‘processed_data.h5’)# 通过key获取数据preprocessed_df = data_store[‘preprocessed_df’]data_store.close()数据存储可以容纳多个表,每个表的名称作为键。关于在Pandas中使用HDFStore的注意事项:您需要安装PyTables> = 3.0.0,因此在安装Pandas之后,请确保更新PyTables,如下所示:pip install –upgrade tables结论如果你觉得你的Pandas项目不够快速,灵活,简单和直观,请考虑重新考虑你使用该库的方式。这里探讨的示例相当简单,但说明了Pandas功能的正确应用如何能够大大改进运行时和速度的代码可读性。以下是一些经验,可以在下次使用Pandas中的大型数据集时应用这些经验法则:尝试尽可能使用矢量化操作,而不是在df 中解决for x的问题。如果你的代码是许多for循环,那么它可能更适合使用本机Python数据结构,因为Pandas会带来很多开销。如果你有更复杂的操作,其中矢量化根本不可能或太难以有效地解决,请使用.apply方法。如果必须循环遍历数组(确实发生了这种情况),请使用.iterrows()或.itertuples()来提高速度和语法。Pandas有很多可选性,几乎总有几种方法可以从A到B。请注意这一点,比较不同方法的执行方式,并选择在项目环境中效果最佳的路线。一旦建立了数据清理脚本,就可以通过使用HDFStore存储中间结果来避免重新处理。将NumPy集成到Pandas操作中通常可以提高速度并简化语法。参考:https://realpython.com/fast-f…如果觉得有帮助,还请给点个赞!欢迎关注我的个人公众号:Python数据科学 ...

February 12, 2019 · 3 min · jiezi

利用 Pandas 将数据集中的某列文本拆分为多行

背景手头的项目要求用 Tableau 创建一个 story,数据集是摩拜上海城区用户使用数据。其中有一个维度的数据处理起来有点棘手。数据格式注意 track 这个维度的数据,它表示的是在订单时间内的行车轨迹,里面包含了大量坐标点。按照 tidydata 的要求:Each variable forms a column.Each observation forms a row.Each type of observational unit forms a table.我需要将 track 的坐标拆分为多行。神来之笔Google 了问题的解决方式,代码是mobike.drop(“track”,axis = 1).join(mobike[“track”].str.split("#",expand = True).stack().reset_index(level = 1,drop = True).rename(“track”))工作原理解决问题不能光知其然,不知其所以然。所以我将这行代码逐语句进行了拆分,一探代码内部的工作原理。最外层代码是:mobike.join({dataset})这里调用了 dataframe 的 join 方法,很基础。{dataset} 这部分做的工作比较多,首先是 split 方法。Python 的 split 方法可以将字符串按照指定的字符进行分割,这个例子中指定的字符是「#」。如果不加参数 expand = True,split()会返回拆分后的字符串数组。mobike[“track”].str.split("#")# [“121.372,31.118”,“121.372,31.119”,“121.373,31.117”,“1…]# [“121.419,31.200”,“121.419,31.201”,“121.420,31.199”,“1…]# …加了 expand = True 会将数组拆开,数组中的每一个元素都会单独保存。mobike[“track”].str.split(”#",expand = True)# “121.372,31.118” “121.372,31.119” “121.373,31.117” “1… # “121.419,31.200” “121.419,31.201” “121.420,31.199” “1…# …到这里相当于将列中所有文本拆成了一个巨大的表,表中每个单元格有一个值。有些行拆分后的元素比较少,没有值可以填充的单元格补充 Nonestack() 会把整个表逐行堆叠成一列。这样就成功的将一列中的所有文本拆分成了多行,而且它是一个 dataframe 。不过到这里还没有结束,我们还需要将拆出来的这个 dataframe 与原数据集合并。注意到拆分出来的 dataframe 是多重索引的,需要用 reset_index() 将多重索引重置掉。在 split() 的时候,我们引入了超级多的 None。这时候就可以通过 reset_index(…, drop =True)将值为 None 的行删除。与原数据集通过 join() 合并的时候,A.join(B),A、B两个 DataFrame 都需要有名字,因此需要 rename(“track”)。至此,我们的任务算做完了。彩蛋我在列拆分为多行的基础上,还将 track 拆分成了两个变量——track_x,track_y。这里用到了 pandas 的函数映射进行数据转换。mobike[“track” = mobike[“track”].split(”,")mobike[“track_x”] = mobike[“track”].map(lambda x:x[0])mobike[“track_y”] = mobike[“track”].map(lambda x:x[1])通过 map 进行列的扩展速度非常非常快。本文用到的摩拜数据及演示 notebook 均可在 DataWranglingMethod下载。 ...

February 12, 2019 · 1 min · jiezi

ApacheCN 学习资源汇总 2019.1

【主页】 apachecn.org【Github】@ApacheCN暂时下线: 社区暂时下线: cwiki 知识库自媒体平台微博:@ApacheCN知乎:@ApacheCNCSDN简书OSChina博客园我们不是 Apache 的官方组织/机构/团体,只是 Apache 技术栈(以及 AI)的爱好者!合作or侵权,请联系【fonttian】<fonttian@gmail.com> | 请抄送一份到 <apachecn@163.com>Java 基础Java 编程思想Java Web 和大数据Spark 2.2.0 中文文档Storm 1.1.0 中文文档Kafka 1.0.0 中文文档Beam 中文文档Zeppelin 0.7.2 中文文档Elasticsearch 5.4 中文文档Kibana 5.2 中文文档Kudu 1.4.0 中文文档Spring Boot 1.5.2 中文文档Airflow 中文文档区块链Solidity 中文文档数学笔记MIT 18.06 线性代数笔记Python 数据科学NumPy 中文文档Pandas 中文文档Matplotlib 中文文档UCB Data8 课本:计算与推断思维UCB Prob140 课本:面向数据科学的概率论UCB DS100 课本:数据科学的原理与技巧利用 Python 进行数据分析 · 第 2 版fast.ai 数值线性代数讲义 v2Pandas Cookbook 带注释源码statsmodels 中文文档数据科学 IPython 笔记本CS 教程LeetCode 中文文档GeeksForGeeks 翻译计划UCB CS61a 课本:SICP Python 描述UCB CS61b 课本:Java 中的数据结构数据结构思维中国大学 MOOC 计算机操作系统笔记简单数据结构实现AI 教程AILearning - 机器学习实战Sklearn 与 TensorFlow 机器学习实用指南面向机器学习的特征工程Python 数据分析与挖掘实战(带注释源码)SciPyCon 2018 Sklearn 教程TensorFlow 学习指南fast.ai 机器学习和深度学习中文笔记HackCV 网站文章翻译台湾大学林轩田机器学习笔记Scikit-learn 秘籍写给人类的机器学习数据科学和人工智能技术笔记AI 文档Sklearn 0.19 中文文档PyTorch 1.0 中文文档XGBoost 中文文档LightGBM 中文文档FastText 中文文档Gensim 中文文档AI 比赛Kaggle 项目实战教程:文档 + 代码 + 视频比赛收集平台其它独立开发/自由职业/远程工作资源列表通往财富自由之路精细笔记5 分钟商学院精细笔记 ...

January 29, 2019 · 1 min · jiezi

pandas指南:做更高效的数据科学家

摘要:Python是开源的,所以有很多开源固有的问题。如果你是Python新手,很难知道针对特定任务的包哪个是最好的。你需要有经验的人来告诉你。今天我要告诉你们的是:在数据科学中,有一个软件包是你们绝对需要学习的,那就是pandas。而pandas真正有趣的地方是,很多其他的包也在里面。pandas是一个核心包,因此它具有来自其他各种包的特性。pandas类似于Python中的Excel:它使用表(即DataFrame)并对数据进行转换,但它还能做更多。如果你已经熟悉Python,可以直接进入第三部分现在让我们开始:import pandas as pdpandas包最基本的功能1、读取数据:data = pd.read_csv(‘my_file.csv’)data=pd.read_csv(‘my_file.csv’,sep=’;’,encoding=‘latin-1’,nrows=1000, kiprows=[2,5])sep变量代表分隔符。因为Excel中的csv分隔符是“;”,因此需要显示它。编码设置为“latin-1”以读取法语字符。nrows=1000表示读取前1000行。skiprows=[2,5]表示在读取文件时将删除第2行和第5行最常用的函数:read_csv, read_excel还有一些很不错的函数:read_clipboard、read_sql2、写入数据data.to_csv(‘my_new_file.csv’, index=None)index=None将简单地按原样写入数据。如果你不写index=None,会得到额外的行。我通常不使用其他函数,比如to_excel,to_json,to_pickle,to_csv,虽然它们也做得很好,但是csv是保存表最常用的方法。3、检查数据:data.shapedata.describe()data.head(3).head(3)打印数据的前3行,.tail()函数将查看数据的最后一行。data.loc[8]打印第8行。data.loc[8, ‘column_1’]将第8行值打印在“column_1”上。data.loc[range(4,6)]打印第4行到第6行。pandas的初级功能1、逻辑运算data[data[‘column_1’]==‘french’]data[(data[‘column_1’]==‘french’) & (data[‘year_born’]==1990)]data[(data[‘column_1’]==‘french’)&(data[‘year_born’]==1990)&(data[‘city’]==‘London’)]如果要根据逻辑操作对数据进行运算,在使用& (AND)、~ (NOT)和| (OR)等逻辑操作之前和之后添加“(”&“)”。data[data[‘column_1’].isin([‘french’, ’english’])]不要为同一列编写多个OR,最好是使用.isin()函数。2、基本绘图多亏了matplotlib包,这个特性才得以实现。就像我们在介绍中说的,它可以直接用在pandas身上。data[‘column_numerical’].plot()data[‘column_numerical’].hist()绘制分布图(直方图)%matplotlib inline如果你使用Jupyter,在绘图之前,不要忘记写这一行(在代码中只写一次)3、更新数据data.loc[8, ‘column_1’] = ’english’将’ column_1 ‘的第8行值替换为’ english ‘data.loc[data[‘column_1’]==‘french’, ‘column_1’] = ‘French’在一行中更改多行值pandas的中级功能现在你可以做一些在Excel中很容易做的事情。让我们来挖掘一些在Excel中做不到的神奇事情。1、计算功能data[‘column_1’].value_counts()2、对全行、全列或所有数据的操作data[‘column_1’].map(len)len()函数应用于“column_1”的每个元素map()操作将一个函数应用于列的每个元素。data[‘column_1’].map(len).map(lambda x : x/100).plot()pandas的另一个特点是进行链式操作。它可以帮助你在一行代码中执行多个操作,从而更加简单和高效。data.apply(sum).apply()将函数应用于列。.applymap()将一个函数应用于表(DataFrame)中的所有单元格。3、tqdm包在处理大型数据集时,pandas可能需要一些时间来运行.map()、.apply()、.applymap()操作。tqdm是一个非常有用的包,它可以帮助预测这些操作何时完成。from tqdm import tqdm_notebooktqdm_notebook().pandas()用pandas设置tqdmdata[‘column_1’].progress_map(lambda x : x.count(’e’))将.map()替换为.progress_map(),.apply()和.applymap()也是一样4、相关矩阵和散射矩阵data.corr()data.corr().applymap(lambda x : int(x*100)/100)pd.plotting.scatter_matrix(data, figsize=(12,8))pandas的高级功能1、行列合并在pandas中,行列合并非常简单。data.merge(other_data, on=[‘column_1’, ‘column_2’, ‘column_3’])合并3列只需要一行代码2、分组分组一开始并不简单,但是如果掌握其语法,你将发现这非常简单。data.groupby(‘column_1’)[‘column_2’].apply(sum).reset_index()按列分组,选择要在其上操作函数的另一列。reset_index()将数据重新生成DataFrame(表)3、遍历行dictionary = {}for i,row in data.iterrows():dictionary[row[‘column_1’]] = row[‘column_2’]iterrows()循环两个变量:行索引和行(上面代码中的i和row)。总体来说,pandas是一个帮助数据科学家快速阅读和理解数据的工具包,它也可以说是Python如此优秀的原因之一。我还可以展示更多pandas包其他有趣的特点,但以上所述足以让人理解为什么数据科学家离不开pandas包。总之,pandas包有以下特点:1、 简单易用,隐藏了所有复杂和抽象的计算;2、非常直观;3、快速。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 25, 2019 · 1 min · jiezi

python之pandas简单介绍及使用

一、 Pandas简介1、Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。2、Pandas 是python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,并于2009年底开源出来,目前由专注于Python数据包开发的PyData开发team继续开发和维护,属于PyData项目的一部分。Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。3、数据结构:Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。Time- Series:以时间为索引的Series。DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。Panel :三维的数组,可以理解为DataFrame的容器。Pandas 有两种自己独有的基本数据结构。读者应该注意的是,它固然有着两种数据结构,因为它依然是 Python 的一个库,所以,Python 中有的数据类型在这里依然适用,也同样还可以使用类自己定义数据类型。只不过,Pandas 里面又定义了两种数据类型:Series 和 DataFrame,它们让数据操作更简单了。二、 Pandas安装因为pandas是python的第三方库所以使用前需要安装一下,直接使用pip install pandas 就会自动安装pandas以及相关组件。三、 Pandas使用注:本次操作是在ipython中进行1、导入pandas模块并使用别名,以及导入Series模块,以下使用基于本次导入。In [1]: from pandas import SeriesIn [2]: import pandas as pd2、SeriesSeries 就如同列表一样,一系列数据,每个数据对应一个索引值。Series 就是“竖起来”的 list:In [3]: s = Series([1,4,‘ww’,’tt’])In [4]: sOut[4]:0 11 42 ww3 ttdtype: object另外一点也很像列表,就是里面的元素的类型,由你任意决定(其实是由需要来决定)。这里,我们实质上创建了一个 Series 对象,这个对象当然就有其属性和方法了。比如,下面的两个属性依次可以显示 Series 对象的数据值和索引:In [5]: s.indexOut[5]: RangeIndex(start=0, stop=4, step=1)In [8]: s.valuesOut[8]: array([1, 4, ‘ww’, ’tt’], dtype=object)列表的索引只能是从 0 开始的整数,Series 数据类型在默认情况下,其索引也是如此。不过,区别于列表的是,Series 可以自定义索引:In [9]: s2 = Series([‘wangxing’,‘man’,24],index=[’name’,‘sex’,‘age’])In [10]: s2Out[10]:name wangxingsex manage 24dtype: object每个元素都有了索引,就可以根据索引操作元素了。还记得 list 中的操作吗?Series 中,也有类似的操作。先看简单的,根据索引查看其值和修改其值:In [12]: s2[’name’]Out[12]: ‘wangxing’In [45]: s2[’name’] = ‘wudadiao’In [46]: s2Out[46]:name wudadiaosex manage 24dtype: object这是不是又有点类似 dict 数据了呢?的确如此。看下面就理解了。读者是否注意到,前面定义 Series 对象的时候,用的是列表,即 Series() 方法的参数中,第一个列表就是其数据值,如果需要定义 index,放在后面,依然是一个列表。除了这种方法之外,还可以用下面的方法定义 Series 对象:In [13]: sd = {‘python’:9000,‘c++’:9001,‘c#’:9000}In [14]: s3 = Series(sd)In [15]: s3Out[15]:c# 9000c++ 9001python 9000dtype: int64现在是否理解为什么前面那个类似 dict 了?因为本来就是可以这样定义的。这时候,索引依然可以自定义。Pandas 的优势在这里体现出来,如果自定义了索引,自定的索引会自动寻找原来的索引,如果一样的,就取原来索引对应的值,这个可以简称为“自动对齐”。In [16]: s4 = Series(sd,index=[‘java’,‘c++’,‘c#’])In [17]: s4Out[17]:java NaNc++ 9001.0c# 9000.0dtype: float64在 Pandas 中,如果没有值,都对齐赋给 NaN。Pandas 有专门的方法来判断值是否为空。In [19]: pd.isnull(s4)Out[19]:java Truec++ Falsec# Falsedtype: bool此外,Series 对象也有同样的方法:In [20]: s4.isnull()Out[20]:java Truec++ Falsec# Falsedtype: bool其实,对索引的名字,是可以从新定义的:In [21]: s4.index = [‘语文’,‘数学’,‘English’]In [22]: s4Out[22]:语文 NaN数学 9001.0English 9000.0dtype: float64对于 Series 数据,也可以做类似下面的运算(关于运算,后面还要详细介绍):In [23]: s4 * 2Out[23]:语文 NaN数学 18002.0English 18000.0dtype: float64In [24]: s4[s4 > 9000]Out[24]:数学 9001.0dtype: float64Series就先简要写到这,下面看pandas的另一种数据结构DataFrame.DataFrameDataFrame 是一种二维的数据结构,非常接近于电子表格或者类似 mysql 数据库的形式。它的竖行称之为 columns,横行跟前面的 Series 一样,称之为 index,也就是说可以通过 columns 和 index 来确定一个主句的位置。首先来导入模块In [27]: from pandas import Series,DataFrameIn [26]: data = {“name”:[‘google’,‘baidu’,‘yahoo’],“marks”:[100,200,300],“price”:[1,2,3]}In [28]: f1 = DataFrame(data)In [29]: f1Out[29]: marks name price0 100 google 11 200 baidu 22 300 yahoo 3这是定义一个 DataFrame 对象的常用方法——使用 dict 定义。字典的“键”(“name”,“marks”,“price”)就是 DataFrame 的 columns 的值(名称),字典中每个“键”的“值”是一个列表,它们就是那一竖列中的具体填充数据。上面的定义中没有确定索引,所以,按照惯例(Series 中已经形成的惯例)就是从 0 开始的整数。从上面的结果中很明显表示出来,这就是一个二维的数据结构(类似 excel 或者 mysql 中的查看效果)。上面的数据显示中,columns 的顺序没有规定,就如同字典中键的顺序一样,但是在 DataFrame 中,columns 跟字典键相比,有一个明显不同,就是其顺序可以被规定,向下面这样做:In [31]: f2 = DataFrame(data,columns=[’name’,‘price’,‘marks’])In [32]: f2Out[32]: name price marks0 google 1 1001 baidu 2 2002 yahoo 3 300跟 Series 类似的,DataFrame 数据的索引也能够自定义In [35]: f3 = DataFrame(data,columns=[’name’,‘marks’,‘price’],index=[‘a’,‘b’,‘c’])In [36]: f3Out[36]: name marks pricea google 100 1b baidu 200 2c yahoo 300 3定义 DataFrame 的方法,除了上面的之外,还可以使用“字典套字典”的方式。In [40]: newdata = {’lang’:{‘first’:‘python’,‘second’:‘java’},‘price’:{‘first’:5000,‘second’:2000}}In [41]: f4 = DataFrame(newdata)In [42]: f4Out[42]: lang pricefirst python 5000second java 2000在字典中就规定好数列名称(第一层键)和每横行索引(第二层字典键)以及对应的数据(第二层字典值),也就是在字典中规定好了每个数据格子中的数据,没有规定的都是空。DataFrame 对象的 columns 属性,能够显示素有的 columns 名称。并且,还能用下面类似字典的方式,得到某竖列的全部内容(当然包含索引):>>> newdata = {“lang”:{“firstline”:“python”,“secondline”:“java”}, “price”:{“firstline”:8000}} f4 = DataFrame(newdata) >>> f4 lang price firstline python 8000 secondline java NaN>>> DataFrame(newdata, index=[“firstline”,“secondline”,“thirdline”]) lang price firstline python 8000 secondline java NaN thirdline NaN NaN DataFrame 对象的 columns 属性,能够显示素有的 columns 名称。并且,还能用下面类似字典的方式,得到某竖列的全部内容(当然包含索引):In [44]: f3[’name’]Out[44]:a googleb baiduc yahooName: name, dtype: object下面操作是给同一列赋值newdata1 = {‘username’:{‘first’:‘wangxing’,‘second’:‘dadiao’},‘age’:{‘first’:24,‘second’:25}}In [67]: f6 = DataFrame(newdata1,columns=[‘username’,‘age’,‘sex’])In [68]: f6Out[68]: username age sexfirst wangxing 24 NaNsecond dadiao 25 NaNIn [69]: f6[‘sex’] = ‘man’In [70]: f6Out[70]: username age sexfirst wangxing 24 mansecond dadiao 25 man也可以单独的赋值,除了能够统一赋值之外,还能够“点对点”添加数值,结合前面的 Series,既然 DataFrame 对象的每竖列都是一个 Series 对象,那么可以先定义一个 Series 对象,然后把它放到 DataFrame 对象中。如下:ssex = Series([‘男’,‘女’],index=[‘first’,‘second’])In [72]: f6[‘sex’] = ssexIn [73]: f6Out[73]: username age sexfirst wangxing 24 男second dadiao 25 女还可以更精准的修改数据吗?当然可以,完全仿照字典的操作:In [74]: f6’age’ = 30In [75]: f6Out[75]: username age sexfirst wangxing 24 男second dadiao 30 女 ...

January 24, 2019 · 2 min · jiezi

python综合学习五之Pandas

这一节,主要深入学习Pandas的用法。一、筛选先建立一个 6X4 的矩阵数据。dates = pd.date_range(‘20180830’, periods=6)df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates, columns=[‘A’,‘B’,‘C’,‘D’])print(df)打印: A B C D2018-08-30 0 1 2 32018-08-31 4 5 6 72018-09-01 8 9 10 112018-09-02 12 13 14 152018-09-03 16 17 18 192018-09-04 20 21 22 23简单的筛选如果我们想选取 DataFrame 中的数据,下面描述了两种途径, 他们都能达到同一个目的:print(df[‘A’])print(df.A)“““2018-08-30 02018-08-31 42018-09-01 82018-09-02 122018-09-03 162018-09-04 20Freq: D, Name: A, dtype: int64"““让选择跨越多行或多列:print(df[0:3]) "”” A B C D2018-08-30 0 1 2 32018-08-31 4 5 6 72018-09-01 8 9 10 11"““print(df[‘20180830’:‘20180901’])””” A B C D2018-08-30 0 1 2 32018-08-31 4 5 6 72018-09-01 8 9 10 11"““如果df[3:3]将会是一个空对象。后者选择20180830到20180901标签之间的数据,并且包括这两个标签。还可以通过 loc, iloc, ix 进行选择。 ...

August 30, 2018 · 1 min · jiezi