暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【分享】 25 个 Pandas 实用技巧

Coding Big Tree 2020-04-30
114

本文一共为大家分享25个pandas技巧。

显示已安装的版本

输入下面的命令查询pandas版本:


    In [7]:pd.__version__
    Out[7]:'0.24.2'


    如果你还想知道pandas所依赖的模块的版本,你可以使用show_versions()函数:


      In [9]:
      pd.show_versions()


      INSTALLED VERSIONS
      ------------------
      commit: None
      python: 3.7.3.final.0
      python-bits: 64
      OS: Darwin
      OS-release: 18.6.0
      machine: x86_64
      processor: i386
      byteorder: little
      LC_ALL: None
      LANG: en_US.UTF-8
      LOCALE: en_US.UTF-8


      pandas: 0.24.2
      pytest: None
      pip: 19.1.1
      setuptools: 41.0.1
      Cython: None
      numpy: 1.16.4
      scipy: None
      pyarrow: None
      xarray: None
      IPython: 7.5.0
      sphinx: None
      patsy: None
      dateutil: 2.8.0
      pytz: 2019.1
      blosc: None
      bottleneck: None
      tables: None
      numexpr: None
      feather: None
      matplotlib: 3.1.0
      openpyxl: None
      xlrd: None
      xlwt: None
      xlsxwriter: None
      lxml.etree: None
      bs4: None
      html5lib: None
      sqlalchemy: None
      pymysql: None
      psycopg2: None
      jinja2: 2.10.1
      s3fs: None
      fastparquet: None
      pandas_gbq: None
      pandas_datareader: None
      gcsfs: None


      你可以查看到Python,pandas, Numpy, matplotlib等的版本信息。


      创建示例DataFrame


      假设你需要创建一个示例DataFrame。有很多种实现的途径,我最喜欢的方式是传一个字典给DataFrame constructor,其中字典中的keys为列名,values为列的取值。



      现在如果你需要创建一个更大的DataFrame,上述方法则需要太多的输入。在这种情况下,你可以使用Numpy的random.rand()函数,告诉它行数和列数,将它传递给DataFrame constructor:




      这种方式很好,但如果你还想把列名变为非数值型的,你可以强制地将一串字符赋值给columns参数




      你可以想到,你传递的字符串的长度必须与列数相同。


      更改列名


      让我们来看一下刚才我们创建的示例DataFrame:




      我更喜欢在选取pandas列的时候使用点(.),但是这对那么列名中含有空格的列不会生效。让我们来修复这个问题。


      更改列名最灵活的方式是使用rename()函数。你可以传递一个字典,其中
      keys为原列名,values为新列名,还可以指定axis:


        In [14]:
        df = df.rename({'col one':'col_one', 'col two':'col_two'}, axis='columns')


        使用这个函数最好的方式是你需要更改任意数量的列名,不管是一列或者全部的列。


        如果你需要一次性重新命令所有的列名,更简单的方式就是
        重写DataFrame的columns属性


          In [15]:
          df.columns = ['col_one''col_two']


          如果你需要做的仅仅是将空格换成下划线,那么更好的办法是使用str.replace()方法,这是因为你都不需要输入所有的列名:


            In [16]:
            df.columns = df.columns.str.replace(' ''_')


            上述三个函数的结果都一样,可以更改列名使得列名中不含有空格:




            最后,如果你需要在列名中添加前缀或者后缀,你可以使用add_prefix()函数




            或者使用add_suffix()函数



            行序反转


            让我们来看一下drinks这个DataFame:


              In [20]:
              drinks.head()


              Out[20]:

              countrybeer_servingsspirit_servingswine_servingstotal_litres_of_pure_alcoholcontinent
              0Afghanistan0000.0Asia
              1Albania89132544.9Europe
              2Algeria250140.7Africa
              3Andorra24513831212.4Europe
              4Angola21757455.9Africa


              该数据集描述了每个国家的平均酒消费量。如果你想要将行序反转呢?

              最直接的办法是使用loc函数并传递::-1,跟Python中列表反转时使用的切片符号一致:


                In [21]:
                drinks.loc[::-1].head()


                Out[21]:

                countrybeer_servingsspirit_servingswine_servingstotal_litres_of_pure_alcoholcontinent
                192Zimbabwe641844.7Africa
                191Zambia321942.5Africa
                190Yemen6000.1Asia
                189Vietnam111212.0Asia
                188Venezuela33310037.7South America

                如果你还想重置索引使得它从0开始呢?


                你可以使用
                reset_index()函数,告诉他去掉完全抛弃之前的索引


                  In [22]:
                  drinks.loc[::-1].reset_index(drop=True).head()


                  Out[22]:

                  countrybeer_servingsspirit_servingswine_servingstotal_litres_of_pure_alcoholcontinent
                  0Zimbabwe641844.7Africa
                  1Zambia321942.5Africa
                  2Yemen6000.1Asia
                  3Vietnam111212.0Asia
                  4Venezuela33310037.7South America


                  你可以看到,行序已经反转,索引也被重置为默认的整数序号。


                  列序反转


                  跟之前的技巧一样,你也可以使用loc函数将列从左至右反转:


                    In [23]:
                    drinks.loc[:, ::-1].head()


                    Out[23]:

                    continenttotal_litres_of_pure_alcoholwine_servingsspirit_servingsbeer_servingscountry
                    0Asia0.0000Afghanistan
                    1Europe4.95413289Albania
                    2Africa0.714025Algeria
                    3Europe12.4312138245Andorra
                    4Africa5.94557217Angola


                    逗号之前的冒号表示选择所有行,逗号之后的::-1表示反转所有的列,这就是为什么country这一列现在在最右边。


                    通过数据类型选择列

                    这里有drinks这个DataFrame的数据类型:


                      In [24]:
                      drinks.dtypes


                      Out[24]:
                      country object
                      beer_servings int64
                      spirit_servings int64
                      wine_servings int64
                      total_litres_of_pure_alcohol float64
                      continent object
                      dtype: object


                      假设你仅仅需要选取数值型的列,那么你可以使用select_dtypes()函数


                        In [25]:
                        drinks.select_dtypes(include='number').head()


                        Out[25]:

                        beer_servingsspirit_servingswine_servingstotal_litres_of_pure_alcohol
                        00000.0
                        189132544.9
                        2250140.7
                        324513831212.4
                        421757455.9


                        这包含了int和float型的列。


                        你也可以使用这个函数来选取数据类型为object的列:




                        你还可以选取多种数据类型,只需要传递一个列表即可:




                        你还可以用来排除特定的数据类型:



                        将字符型转换为数值型

                        让我们来创建另一个示例DataFrame:




                        这些数字实际上储存为字符型,导致其数据类型为object:




                        为了对这些列进行数学运算,我们需要将数据类型转换成数值型。你可以对前两列使用astype()函数




                        但是,如果你对第三列也使用这个函数,将会引起错误,这是因为这一列包含了破折号(用来表示0)但是pandas并不知道如何处理它。

                        你可以对第三列使用to_numeric()函数,告诉其将任何无效数据转换为NaN:




                        如果你知道NaN值代表0,那么你可以fillna()函数将他们替换成0:




                        最后,你可以通过apply()函数一次性对整个DataFrame使用这个函数:




                        仅需一行代码就完成了我们的目标,因为现在所有的数据类型都转换成float:



                        减小DataFrame空间大小


                        pandas DataFrame被设计成可以适应内存,所以有些时候你可以减小DataFrame的空间大小,让它在你的系统上更好地运行起来。


                        这是drinks这个DataFrame所占用的空间大小:




                        可以看到它使用了30.4KB。


                        如果你对你的DataFrame有操作方面的问题,或者你不能将它读进内存,那么在读取文件的
                        过程中有两个步骤可以使用来减小DataFrame的空间大小。


                        第一个步骤是只读取那些你实际上需要用到的列,可以调用usecols参数:




                        通过仅读取用到的两列,我们将DataFrame的空间大小缩小至13.6KB。


                        第二步是将所有实际上为类别变量的object列转换成类别变量,可以调用dtypes参数:




                        通过将continent列读取为category数据类型,我们进一步地把DataFrame的空间大小缩小至2.3KB。


                        值得注意的是,如果跟行数相比,category数据类型的列数相对较小,那么catefory数据类型可以减小内存占用。


                        按行从多个文件中构建DataFrame

                        假设你的数据集分化为多个文件,但是你需要将这些数据集读到一个DataFrame中。


                        举例来说,我有一些关于股票的小数聚集,每个数据集为单天的CSV文件。这是第一天的:




                        这是第二天的:




                        这是第三天的:




                        你可以将每个CSV文件读取成DataFrame,将它们结合起来,然后再删除原来的DataFrame,但是这样会多占用内存且需要许多代码


                        更好的方式为使用内置的glob模块。你可以给glob()函数传递某种模式,包括未知字符,这样它会返回符合该某事的文件列表。在这种方式下,glob会查找所有以stocks开头的CSV文件:




                        glob会返回任意排序的文件名,这就是我们为什么要用Python内置的sorted()函数来对列表进行排序。


                        我们以生成器表达式用read_csv()函数来读取每个文件,并将结果传递给concat()函数,这会将单个的DataFrame按行来组合:




                        不幸的是,索引值存在重复。为了避免这种情况,我们需要告诉concat()函数来忽略索引,使用默认的整数索引:



                        按列从多个文件中构建DataFrame


                        上一个技巧对于数据集中每个文件包含行记录很有用。但是如果数据集中的每个文件包含的列信息呢?


                        这里有一个例子,dinks数据集被划分成两个CSV文件,每个文件包含三列:




                        同上一个技巧一样,我们以使用glob()函数开始。这一次,我们需要告诉concat()函数按列来组合:




                        现在我们的DataFrame已经有六列了。


                        文章转载自Coding Big Tree,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论