zoukankan      html  css  js  c++  java
  • 【机器学习算法应用和学习_1_基础篇】1.2 pandas

    注:为了能系统性学习pandas,我这篇文章将会根据官网的文档结构结合工作中需求场景进行梳理。目的有三,一是尽量介绍全面,二是核心是能解决工作的需求,三是在特定需求下也能快速找到官网中的解决办法。

    注:一般很少用series,以下一般只看dataframe。

    官网:https://pandas.pydata.org/pandas-docs/stable/index.html

    一、准备开始

    ——这部分主要介绍pandas的作用、数据结构和注意点等,可以大概看一眼有个印象即可。

    1.1 Pandas包概述

       pandas是一个Python包,提供快速、灵活和富有表现力的数据结构,旨在使处理“关系”或“标记”数据既简单又直观。它的目标是成为用Python进行实际的、真实的数据分析的基本高层构建块。此外,它还有一个更广泛的目标,即成为任何语言中可用的最强大、最灵活的开源数据分析/操作工具。它已经在朝着这个目标迈进。

    pandas非常适合许多不同类型的数据:

    具有不同类型列的表格数据,如在SQL表或Excel电子表格中

    有序和无序(不一定是固定频率)时间序列数据。

    具有行和列标签的任意矩阵数据(均匀类型或异构类型)

    任何其他形式的观察/统计数据集。这些数据实际上根本不需要标记就可以放入panda数据结构中

    pandas的两个主要数据结构Series(一维)和DataFrame(二维),能处理金融、统计、社会科学和许多工程领域的绝大多数典型用例。对于R用户,DataFrame提供了R的data.frame提供的所有内容,甚至更多。panda构建在NumPy之上,旨在与许多其他第三方库很好地集成在科学计算环境中。

    以下是pandas擅长的几件事:

    -易于处理浮点数据和非浮点数据中丢失的数据(用NaN表示)

    -大小可变性:可以从DataFrame和高维对象中插入和删除列

    -自动和显式数据对齐:对象可以显式对齐到一组标签上,或者用户可以简单地忽略标签,让Series、DataFrame等在计算中为您自动对齐数据

    -功能强大、灵活的group by功能,可以对数据集执行拆分-应用-组合操作,用于聚合和转换数据

    -简化将其他Python和NumPy数据结构中不规则的、不同索引的数据转换为数据aframe对象的过程

    -基于智能标签的切片、花式索引和大型数据集的子集

    -直观的合并和连接数据集

    -数据集的灵活重设和旋转

    -轴的分层标记(每块可能有多个标记)

    -健壮的IO工具,用于从平面文件(CSV和分隔符)、Excel文件、数据库中加载数据,以及从超快HDF5格式中保存/加载数据

    -时间序列特有的功能:日期范围生成和频率转换、移动窗口统计、移动窗口线性回归、日期移位和滞后等。

    这里的许多原则都是为了解决使用其他语言/科学研究环境时经常遇到的缺点。对于数据科学家来说,处理数据通常分为多个阶段: 数据转换和清理,数据分析/建模,然后将分析结果组织成适合绘图或表格显示的形式。pandas是所有这些任务的理想工具。

    其他一些笔记:

    -pandas很快。Cython代码中对许多底层算法位进行了广泛的调整。然而,与其他任何泛化方法一样,泛化通常会牺牲性能。因此,如果您专注于应用程序的一个特性,您可能能够创建一个更快的专用工具。

    -pandas是statsmodels库的依赖项,这使得它成为Python统计计算生态系统的重要组成部分。

    -pandas已被广泛用于生产和金融应用。

    1.2 数据结构

    维数

    名称

    描述

    1

    Series

    一维相同类型的标签数组

    2

    DataFrame

    一般是二维标签,有大小可变的表格结构与潜在的不同类型列

    为什么要有超过1种数据结构?

    理解pandas数据结构的最佳方法是将其作为低维度数据的灵活容器。例如,DataFrame是Series的容器,Series是标量的容器。我们希望能够以类似词典的方式从这些容器中插入和删除对象。

    此外,我们希望考虑时间序列和横断面数据集的典型方向的公共API函数的合理默认行为。当使用ndarrays存储2维和3维数据时,用户在编写函数时需要考虑数据集的方向;轴被认为或多或少是等价的(除非C或fortran关系到性能)。在pandas中,坐标轴的作用是赋予数据更多的语义;即,对于特定的数据集,可能有一种“正确”的方法来确定数据的方向。因此,目标是减少在下游函数中编码数据转换所需的脑力劳动。

    例如,对于表格数据(DataFrame),考虑索引(行)和列比考虑轴0和轴1在语义上更有帮助。因此,遍历DataFrame的列会得到可读性更好的代码:

    for col in df.columns:

        series = df[col]

        # do something with series

    ——意思是如果只有多维数组这种结构,我们遍历时得考虑数据维度的方向,而这种一维数组和维度平铺的二维数组的结构,在遍历维度(列)时就很好理解了。

    数据的可变性和复制性

    所有pandas数据结构都是值可变的(它们包含的值可以更改),但并不总是大小可变的。序列的长度不能更改,但是,例如,可以将列插入到DataFrame中。然而,绝大多数方法都会生成新的对象,并且不改变输入数据。一般来说,我们喜欢在合理的地方保持不变。

    ——意思是值都是可以更改的,但序列长度不能更改(?暂时不太清楚什么意思)。而且调用更改方法绝大多数不会改变原来的对象,而是得赋值给新的对象或赋值给原对象才能看到更新后的数据。

    1.3 获得帮助

    pandas问题和想法的第一站是ithub Issue Tracker。如果你有一个一般性的问题,熊猫社区的专家可以通过Stack Overflow来回答。

    二、10分钟入门pandas

    ——这部分对pandas的各项功能做了简单介绍和示例,刚入门可以稍微看一下。但我需要按自己的需求思路梳理文档,所以这部分暂时不更。

    按照惯例,我们这么引入:

    import numpy as np

    import pandas as pd

    import matplotlib.pyplot as plt

    三、用户导引

    ——这部分是介绍pandas用法的主要章节,以下会按照我的需求梳理成文,适当调整结构并跳过一些暂不需要的内容。

     3.0 应用背景

      在进入这个章节前,我们首先思考以下几点,避免一味深入学pandas结果陷入不重要的细枝末节而浪费时间。

    1.为什么学pandas?通过前面的介绍和你过往经验,你知道pandas大概能帮你做什么?

    学pandas有两个原因,

    一是初级分析师一般都是用Excel,当然好一点有类tableau工具,但Excel只能处理100w条记录并且在特征非常多时可能20w条不到就已经卡疯了,当需要灵活处理大量明细数据时,用pandas会比较方便(而不是用n多条SQL跑出一堆聚合数据,而且有时一条SQL的n多维度的聚合数据也能有几十万条记录);

    二是在进行机器学习时,pandas在预处理上也更方便。

    我大概了解到pandas可以做 数据IO、数据筛选转换、缺失值处理、group by、透视表、绘图等。

    2.工作中的使用路径是怎样的?只要主要(覆盖80%使用场景)功能时,大概是这样的学习路径?

    数据生成和写入(包括创建简单辅助表,读取csv文件)-

    查看数据大概啥样、每列缺失值、简单描述统计(离散值每个值的分布,连续值直方图分布)、数据类型(看需不需要转换,特别是时间类型)-

    缺失值或特殊条件赋值处理(缺失值处理好理解,特殊条件比如某个某些条件下的值错了或字符串改别名好理解)-

    不同程度的筛选切片(比如某列、某行、某些行某些列、某行某列、某些条件)-

    维度计算(比如连续数据分桶、多个维度根据某个判断逻辑生成一个新的维度、日期计算、字符串计算)-

    度量计算(除了常见的聚合可能还有一些特定公式计算,参考SQL 的group by和Excel的透视表甚至tableau的度量计算逻辑)-

    单特征或多特征绘图-

    保存文件(写入csv文件,保存分析图表等)

    3.在你学完这章节之后,review一下你pandas的使用路径,并介绍一下没深入的功能点和链接(学完后回答)?

      以下是官网的目录,留个印象:

    数据IO
    索引和筛选
    多重索引/高级索引
    合并数据
    重塑和透视表
    文本数据处理
    缺失数据处理
    分类数据处理
    可为空整数类型
    可视化
    计算工具
    group by:分类-应用-结合
    时间序列/日期功能
    时间增减
    风格
    选项和设置
    增强性能
    稀疏数据结构
    FAQ
    cookbook

      以下根据应用需求重塑章节框架和内容。

    3.1 数据IO

    1)创建数据

    参考:https://pandas.pydata.org/pandas-docs/stable/getting_started/10min.html#object-creation

    通过传入字典创建:

    In [9]: df2 = pd.DataFrame({'A': 1.,
       ...:                     'B': pd.Timestamp('20130102'),
       ...:                     'C': pd.Series(1, index=list(range(4)), dtype='float32'),
       ...:                     'D': np.array([3] * 4, dtype='int32'),
       ...:                     'E': pd.Categorical(["test", "train", "test", "train"]),
       ...:                     'F': 'foo'})
       ...: 
    
    In [10]: df2
    Out[10]: 
         A          B    C  D      E    F
    0  1.0 2013-01-02  1.0  3   test  foo
    1  1.0 2013-01-02  1.0  3  train  foo
    2  1.0 2013-01-02  1.0  3   test  foo
    3  1.0 2013-01-02  1.0  3  train  foo
    通过传入字典创建df

    通过传入NumPy的多维数组创建:

    In [5]: dates = pd.date_range('20130101', periods=6)
    
    In [6]: dates
    Out[6]: 
    DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
                   '2013-01-05', '2013-01-06'],
                  dtype='datetime64[ns]', freq='D')
    
    In [7]: df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
    
    In [8]: df
    Out[8]: 
                       A         B         C         D
    2013-01-01  0.469112 -0.282863 -1.509059 -1.135632
    2013-01-02  1.212112 -0.173215  0.119209 -1.044236
    2013-01-03 -0.861849 -2.104569 -0.494929  1.071804
    2013-01-04  0.721555 -0.706771 -1.039575  0.271860
    2013-01-05 -0.424972  0.567020  0.276232 -1.087401
    2013-01-06 -0.673690  0.113648 -1.478427  0.524988
    通过传入NumPy的多维数组创建df

    2)数据写入

    参考:https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html

    pandas支持很多格式的IO,都是使用read和to的函数,如下:

    但为了快速掌握,这里先只介绍CSV的IO,其他有需要时再补充。

    read_csv()

    快捷代码:

    函数参数众多,以下从不同使用场景考虑提供快捷代码。

    #0.文件是正常CSV文件,且存在python本地,有表头
    #————因为是默认以逗号分隔,表头自动推断。
    df0= pd.read_csv('foo.cav')
    #1.文件是正常的CSV文件(或以以逗号分隔的),有表头,存在在某个文件路径下

    df1= pd.read_csv('E://data/foo.cav')
    #2.文件是以以/t分隔的,有表头
    df2= pd.read_csv('E://data/foo.txt',sep='s+')
    df2= pd.read_csv('E://data/foo.txt',delim_whitespace=True)#这个比较管用

    #3.文件没有表头,需要设置表头
    #—————参数说明告诉我们设置names时要指定header=None,但不设置header也是可以的
    df3=pd.read_csv('E://data/foo.csv',sep='s+',header=None,names=['id','姓名'])

    #4.文件需要忽略源文件的第一行表头,重新设置表头
    #————需要跳过skiprows第一行数据,并设置names

    df4=pd.read_csv('E://data/foo.csv',sep='s+',header=None,skiprows=1,names=['id','姓名'])

    常用参数:

    3)数据输出

    快捷代码:

    #1.输出到某个路径文件
    df.to_csv('E://data/foo.csv')

    3.2 数据查看和格式转换

    参考:https://pandas.pydata.org/pandas-docs/stable/getting_started/10min.html#viewing-data

    1.查看前后几行(默认5行):

    目的:一般是查看表结构,看导入结果是否正常。

    In [13]: df.head()
    Out[13]: 
                       A         B         C         D
    2013-01-01  0.469112 -0.282863 -1.509059 -1.135632
    2013-01-02  1.212112 -0.173215  0.119209 -1.044236
    2013-01-03 -0.861849 -2.104569 -0.494929  1.071804
    2013-01-04  0.721555 -0.706771 -1.039575  0.271860
    2013-01-05 -0.424972  0.567020  0.276232 -1.087401
    
    In [14]: df.tail(3)
    Out[14]: 
                       A         B         C         D
    2013-01-04  0.721555 -0.706771 -1.039575  0.271860
    2013-01-05 -0.424972  0.567020  0.276232 -1.087401
    2013-01-06 -0.673690  0.113648 -1.478427  0.524988
    df查看前后几行

    2.缺失值处理和数据类型转换

    1)查看空值数和数据类型:

    目的:一般是看数据源每列空值是否存在异常,先考虑怎么处理;再看每列的数据格式是否是需要的,比如带千分位的数字、日期格式等会自动识别成字符类型(object),需要进行转换。

    df.info()
    #结果
    <class 'pandas.core.frame.DataFrame'>
    Index: 6 entries, a to f
    Data columns (total 4 columns):
    A    6 non-null float64
    B    6 non-null float64
    C    6 non-null float64
    D    6 non-null float64
    dtypes: float64(4)
    memory usage: 240.0+ bytes
    
    df.dtype #也可以查看每列数据类型
    df查看空值数和数据类型

    2)缺失值处理

     缺失值处理有几种方式:

    (1) 删除含缺失值的列;

    df.dropna(axis=0)#删除确实值的行
    dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)#inplace=False表示直接在df源数据上改而不是创建副本

    (2)填充某个固定值;

    df.fillna(0)#填充0
    df.fillna(0['列名1':‘列名3’)#只对列名1:列名3的列处理
    df['列名'].fillna(0)
    fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)#inplace=False表示直接在df源数据上改而不是创建副本

    (3)填充该列均值、中位数;

    df['列名'].fillna(df['列名'].mean())

    (4)填充前一或后一值(适用于时间序列);

    df['列名'].fillna(method='pad',limit=1)#填充前一行值,多个连续空值只填1个
    
    df['列名'].fillna(method='bfill',limit=1)#填充后一行值,多个连续空值只填1个

    (5)填充其他列对应值

    df.loc[df['列名A'].isnull(),'列名A']=df[df['列名A'].isnull()][‘列名B’] 

    3)数据类型转换

    pandas数据类型与Python/numpy数据类型对应表如下:

     转换数据类型有几种方式:

    (1).在pd.read_cav读取是通过设置dtype={'列名':‘’数据类型}或converters={'列名':‘’数据类型可调用函数}这俩参数进行设置;

    (2).通过astype强制转化数据类型,格式为:df['列名'] =df['列名'].astype(‘数据类型’);

    (3).通过创建自定义的函数或lamba列表推导式进行数据转化,再应用df['列名'].apply(可调用函数),这个方法可用于去除货币符号、逗号等转换成数值类型的操作;

    (4).pandas提供的to_numeric()、to_datetime()等。

    #将Jan Units列的coerce替换成0
    df["Jan Units"]=pd.to_numeric(df["Jan Units"],errors='coerce').fillna(0)
    
    #将年月日三列合并成日期创建新列YMD
    df["YMD"]=pd.to_datetime(df[['Month', 'Day', 'Year']])

    参考:https://www.cnblogs.com/onemorepoint/p/9404753.html

    3.查看描述性统计

    1)查看描述统计:

    In [19]: df.describe()
    Out[19]: 
                  A         B         C         D
    count  6.000000  6.000000  6.000000  6.000000
    mean   0.073711 -0.431125 -0.687758 -0.233103
    std    0.843157  0.922818  0.779887  0.973118
    min   -0.861849 -2.104569 -1.509059 -1.135632
    25%   -0.611510 -0.600794 -1.368714 -1.076610
    50%    0.022070 -0.228039 -0.767252 -0.386188
    75%    0.658444  0.041933 -0.034326  0.461706
    max    1.212112  0.567020  0.276232  1.071804

    2)查看描述性绘图:

    import matplotlib.pyplot as plt
    #3.查看描述性统计
    #Xy.describe()
    #离散变量需要分组聚合,连续变量直接查看直方图
    fig, axs = plt.subplots(5, 2, figsize=(20, 20))
    Xy.groupby('a')['y'].count().plot.bar(title='a',ax = axs[0,0],color='K')
    Xy.groupby('b')['y'].count().plot.bar(title='b',ax = axs[0,1],color='K')
    Xy.groupby('c')['y'].count().plot.bar(title='c',ax = axs[1,0],color='K')
    Xy.groupby('d')['y'].count().plot.bar(title='d',ax = axs[1,1],color='K')
    Xy.groupby('e')['y'].count().plot.bar(title='e',ax = axs[2,0],color='K')
    Xy.groupby('f')['y'].count().plot.bar(title='f',ax = axs[2,1],color='K')
    Xy['g'].plot.hist(title='g',ax = axs[3,0],color='K')
    Xy['h'].plot.hist(title='h',ax = axs[3,1],color='K')
    Xy['i'].plot.hist(title='i',ax = axs[4,0],color='K')
    plt.show()

    4.其他

    查看索引和列名:

    Xy.index
    Xy.columns

    df行列转置:

    In [20]: df.T
    Out[20]: 
       2013-01-01  2013-01-02  2013-01-03  2013-01-04  2013-01-05  2013-01-06
    A    0.469112    1.212112   -0.861849    0.721555   -0.424972   -0.673690
    B   -0.282863   -0.173215   -2.104569   -0.706771    0.567020    0.113648
    C   -1.509059    0.119209   -0.494929   -1.039575    0.276232   -1.478427
    D   -1.135632   -1.044236    1.071804    0.271860   -1.087401    0.524988
    df行列转置

    df格式转换:

    #dataframe转成numpy的多维数组
    In [18]: df2.to_numpy()
    Out[18]: 
    array([[1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'test', 'foo'],
           [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'train', 'foo'],
           [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'test', 'foo'],
           [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'train', 'foo']],
          dtype=object)
    df格式转换

     df复制:

    dfa = df.copy()
    df复制

    3.3 数据筛选切片

    1)【查】排序

    一般我们习惯看原始数据以及聚合后的最大最小值,方便大概看异常值情况。

    其中,聚合后即group by/pivot方法里也有排序参数,但其结果本身也是多重索引的dataframe,也可以通过赋值副本利用下面的方法重新排序。

    DF排序
    功能 函数/方法 语法 常用参数
    按轴(索引名或列名)排序  DataFrame.sort_index DataFrame.sort_index(self[, axis, level, …])

    axis: (0 or ‘index’, 1 or ‘columns’)对行还是对列排序。0即对索引进行排序,1即对列名排序,默认0;

    ascending:默认True升序;

    level:(int or level name or list of ints or list of level names)多重索引时,可指定排序的索引。

    按某列或某些列排序 DataFrame.sort_values DataFrame.sort_values(self, by[, axis, …])

    axis: (0 or ‘index’, 1 or ‘columns’)对行还是对列排序。0即对索引进行排序,1即对列名排序,默认0;

    by : (str or list of str)要排序的名称或名称列表。

     如果axis是0或' index ',那么by可能包含索引级别和/或列标签

    如果axis是1或' columns ',那么by可能包含列级别和/或索引标签

    ascending:(bool or list of bool, default True)升序排序和降序排序。为多个排序顺序指定列表。如果这是一个布尔列表,则必须匹配by的长度。

    inplace : (bool, default False)如果true,则修改原始数据,而不是建立副本

    na_position: {' first ', ' last ' default ' last '},NaN的位置,first 把NaNs放在开头;last 把NaNs放在最后。

    #最常用的是对索引排序
    df.sort_index()
    #对列排序,很少有这样的
    In [21]: df.sort_index(axis=1, ascending=False) Out[21]: D C B A 2013-01-01 -1.135632 -1.509059 -0.282863 0.469112 2013-01-02 -1.044236 0.119209 -0.173215 1.212112 2013-01-03 1.071804 -0.494929 -2.104569 -0.861849 2013-01-04 0.271860 -1.039575 -0.706771 0.721555 2013-01-05 -1.087401 0.276232 0.567020 -0.424972 2013-01-06 0.524988 -1.478427 0.113648 -0.673690

    #按某列值排序
    In [22]: df.sort_values(by='B')
    Out[22]: 
                       A         B         C         D
    2013-01-03 -0.861849 -2.104569 -0.494929  1.071804
    2013-01-04  0.721555 -0.706771 -1.039575  0.271860
    2013-01-01  0.469112 -0.282863 -1.509059 -1.135632
    2013-01-02  1.212112 -0.173215  0.119209 -1.044236
    2013-01-06 -0.673690  0.113648 -1.478427  0.524988
    2013-01-05 -0.424972  0.567020  0.276232 -1.087401

    #按某两列值排序
    df.sort_values(by=['col1', 'col2'])
        col1 col2 col3
    1   A    1    1
    0   A    2    0
    2   B    9    9
    5   C    4    3
    4   D    7    2
    3   NaN  8    4
     

    2)【查】简单筛选

    简单的筛选包括选取某列、某些列、某行、某些行、某行某列、某些行(连续或不连续)某些列(连续或不连续)。

    这里先介绍pandas的几种索引方式,再通过实例比较说明。

    DF几种索引方式
    功能 函数/方法 语法 描述 常用参数
    选择某列某些列 df[]

    对象类型

    语法

    返回值类型

    Series

    series[label]

    标量值(即某个某些值)

    DataFrame

    frame[colname]

    某列某些列(1列是一个series)

    使用[]建立索引的主要功能是选择低维切片,相当于类里面的getitem__方法。

    1)其中,由于dataframe是有多个series列构成,所以也可以通过df[][]访问某个具体的值,但不推荐这样链式访问,有时候会出问题。

    1.一个列名,df['A'];
    2.一个列名列表,df[['A', 'B']];
    3.一个布尔值数组,df[df['A']>0.5];
    4.一个可调用的函数。

    选择某列 df.列名 df.列名

    dataframe的每列也是属性,可以使用属性访问的方式访问某列。

    1)注意,不要通过属性访问方式创建新列,这样只会创建一个新的属性,并不会创建新列,例如df.E=5并不能创建E列。

    按标签(名称)任意索引切片 df.loc[]

    对象类型

    语法

    Series

    s.loc[indexer]

    DataFrame

    df.loc[row_indexer,column_indexer]

    主要是基于标签的,但也可以与布尔数组一起使用。

    1)一般格式为df.loc[:,:],逗号前是行索引,逗号后是列索引,逗号不可省,行索引不可为无(可以是空片:);

    2)要求的每个标签必须在索引中,否则将引发密钥错误。在进行切片时,如果索引中有开始边界和停止边界,则开始边界和停止边界都包括在内;

    3)整数是有效的标签,但是它们引用的是标签而不是位置。

    indexer/row_indexer/column_indexer可以是:
    1.单个标签,例如5或' A '(注意5被解释为索引的一个标签——即dataframe表示列名,series里表示行名。不是一个沿索引的整数位置。);
    2.标签的列表或数组[' A ', 'b', 'c'];
    3.一个带有' A ':'f'标签的切片对象(注意,与通常的python切片不同,在索引中出现时,开始和结束都包含在内!参见带有标签的切片,并且包含端点);
    4.一个布尔值数组;
    5.一个可调用的函数,带有一个参数(调用序列或DataFrame),返回有效的索引输出(上面的一个)。

    按索引位置任意索引切片 df.iloc[]

    对象类型

    语法

    Series

    s.loc[indexer]

    DataFrame

    df.loc[row_indexer,column_indexer]

    主要是基于整数位置的(从0开始)的,但也可以与布尔数组一起使用。

    1)格式同上,但切片时不含上界,即1:4返回的是第2到第3。

    indexer/row_indexer/column_indexer可以是:
    1.一个整数,例如5。
    2.整数的列表或数组[4,3,0]。
    3.带有整型1:7的切片对象(注意不含上界)。
    4.一个布尔值数组。
    5.一个可调用的函数,带有一个参数(调用序列或DataFrame),返回有效的索引输出(上面的一个)。

    按标签(名称)索引某行某列 df.at[]  
    df.at[ScalarAccessIndexer]

     基于标签,索引某一行某一列。

    1)取某一行某一列的值,速度比df.loc[]快一点。

     df.at[2,'B']
    索引位置索引某行某列 df.iat[]  
    df.iat[ScalarAccessIndexer]
     

    基于整数位置,索引某一行某一列。

    1)取某一行某一列的值,速度比df.loc[]快一点。

     df.at[2,2]
    #下面实例用到的DataFrame
    
    In [44]: df1 = pd.DataFrame(np.random.randn(6, 4),
       ....:                    index=list('abcdef'),
       ....:                    columns=list('ABCD'))
       ....: 
    
    In [45]: df1
    Out[45]: 
              A         B         C         D
    a  0.132003 -0.827317 -0.076467 -1.187678
    b  1.130127 -1.436737 -1.413681  1.607920
    c  1.024180  0.569605  0.875906 -2.211372
    d  0.974466 -2.006747 -0.410001 -0.078638
    e  0.545952 -1.219217 -1.226825  0.769804
    f -1.281247 -0.727707 -0.121306 -0.097883
    实例 df[] df.A df.loc[] df.iloc[] df.at[] df.iat[]
     选择某1列 df['B'] df.B df.loc[:,'B'] df.iloc[:,1] - -
     选择某些连续列 列名需要枚举,用法同选择某些不连续列 - df.loc[:,'B':'D'] df.iloc[:,1:4] - -
     选择某些不连续列 df[['B','D']] - df.loc[:,['B','D']] df.iloc[:,[1,3]] -
     选择某1行 - - df.loc['b'] df.iloc[1] - -
     选择某些连续行 - - df.loc['b':'d'] df.iloc[1:4] - -
    选择某些不连续行 - - df.loc[['b','d']] df.iloc[[1,3]] - -
    选择某些连续行某些连续列 - - df.loc['b':'d','B':'D'] df.iloc[1:4,1:4] - -
    选择某些不连续行某些不连续列 - - df.loc[['b','d'],['B','D']] df.iloc[[1,3],[1,3]] - -
    选择某1行某1列

    df['B']['b']
    df['B'][1]

    df.B.b df.loc['b','B'] df.iloc[1,1] df.at['b','B'] df.iat[1,1]
    #你也可以将一个dict赋值给一个DataFrame的行
    In [24]: x = pd.DataFrame({'x': [1, 2, 3], 'y': [3, 4, 5]})
    
    In [25]: x.iloc[1] = {'x': 9, 'y': 99}
    
    
    s[::2]#这是一种不知道的方式,看起来是以2step索引
    df[::-1]#显然这是一个倒序输出

    #布尔数组长度要匹配相应的行或列长度
    In [49]: df1.loc['a'] > 0
    Out[49]: 
    A     True
    B    False
    C    False
    D    False
    Name: a, dtype: bool
     
    In [50]: df1.loc[:, df1.loc['a'] > 0]
    Out[50]: 
              A
    a  0.132003
    b  1.130127
    c  1.024180
    d  0.974466
    e  0.545952
    f -1.281247
     

    3)【查】复杂筛选

    简单筛选的实例都是比较简单的场景,但事实上在实际应用中,直接索引切片的情况很少,顶多是选择某些列(某列有意义的特征)。更多时候我们需要筛选某些列条件得到子集进行其他动作,或者进行维度计算。所以这里要继续介绍前面没太提及的布尔数组参数、可调用函数参数,以及query()方法、where()方法、isin、get()方法、lookup()方法、随机选择等。

    3.4 维度计算(计算列)

    注:光看官网文档很难按我的需求总结,所以大多先搜索需要的案例,后续再扩展梳理。ps.用bing英文搜索非常有效,很多我需要的都在stackoverflow有类似案例,尤其国外的回答者还喜欢列出不同的解决方案及每种方案的耗时,非常方便。

    1)【增】无条件增加辅助列

    2)【增】按条件增加列

    增加一列,判断某列为空时赋值为0,不为空时赋值为1:

    (1.用于将不必细分的特征改成二分类特征)

    https://stackoverflow.com/questions/38607381/python-pandas-if-the-data-is-nan-then-change-to-be-0-else-change-to-be-1-in-d

    3)【删】删除行列

    删除列:

    del Xy['列名']

    4)【改】无条件改值

    4)【改】按条件改值

    5)字符串处理

    6)日期计算

    获取datetime64类型列的年月:

    (1.用于看年月分布,因为年月日粒度太细了)

    https://stackoverflow.com/questions/45304531/extracting-the-first-day-of-month-of-a-datetime-type-column-in-pandas

    计算两列日期的差值或与某一固定日期的差值:

    (1.用于重构时间特征,很多场景下,日期并不是有效特征,日期差值才是。例如最后活跃日期需要改成最后一次活跃日期距今天数。)

    #以下,a1列和a2列都是datetime类型
    #计算a1-a2日期差
    df['a']=(df['a1'] - df['a2'])/pd.offsets.Day(1)
    df['a']=(df['a1'] - df['a2']).dt.days
    #计算2019-03-31与a1列日期差
    df['a']=(pd.to_datetime('31-03-2019')-df['a1'])/pd.offsets.Day(1)

    另,计算日期差的月值参考:

    https://stackoverflow.com/questions/37078370/pandas-function-equivalent-to-sqls-datediff#

    3.5 度量计算(计算度量)

    1)groupby

    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)})
    
    df.groupby('A').count()#按A列分组,对其他列进行count计算
    df.groupby('A')['A'].count()#按A列分组,对A列进行count计算
    df.groupby('A')['C'].sum()#按A列分组,对C列进行sum计算
    df.groupby('A')['C'].agg(['count', 'sum'])#按A列分组,对C列进行count和sum计算
    df.groupby(['A','B'])['C'].agg(['count', 'sum'])#按AB列分组,对C列进行count和sum计算
    df.groupby(['A','B'])['C','D'].agg(['count', 'sum'])#按AB列分组,对CD列进行count和sum计算
    df.groupby(['A','B'])['C','D'].agg(['count', 'sum']).reset_index()#按AB列分组,对CD列进行count和sum计算,并将索引平铺

    常用的聚合函数:

    In [91]: bb = pd.read_csv('data/baseball.csv', index_col='id')
    
    In [92]: (bb.groupby(['year', 'team']).sum()
       ....:    .loc[lambda df: df.r > 100])
       ....: 
    Out[92]: 
               stint    g    ab    r    h  X2b  X3b  hr    rbi    sb   cs   bb     so   ibb   hbp    sh    sf  gidp
    year team                                                                                                      
    2007 CIN       6  379   745  101  203   35    2  36  125.0  10.0  1.0  105  127.0  14.0   1.0   1.0  15.0  18.0
         DET       5  301  1062  162  283   54    4  37  144.0  24.0  7.0   97  176.0   3.0  10.0   4.0   8.0  28.0
         HOU       4  311   926  109  218   47    6  14   77.0  10.0  4.0   60  212.0   3.0   9.0  16.0   6.0  17.0
         LAN      11  413  1021  153  293   61    3  36  154.0   7.0  5.0  114  141.0   8.0   9.0   3.0   8.0  29.0
         NYN      13  622  1854  240  509  101    3  61  243.0  22.0  4.0  174  310.0  24.0  23.0  18.0  15.0  48.0
         SFN       5  482  1305  198  337   67    6  40  171.0  26.0  7.0  235  188.0  51.0   8.0  16.0   6.0  41.0
         TEX       2  198   729  115  200   40    4  28  115.0  21.0  4.0   73  140.0   4.0   5.0   2.0   8.0  16.0
         TOR       4  459  1408  187  378   96    2  58  223.0   4.0  2.0  190  265.0  16.0  12.0   4.0  16.0  38.0

     2)pivot

    3.6 可视化

    1.基础绘图:

    dateframe的plot()方法是对plt.plot()的简单封装。

    功能 语法 描述 常用参数
    折线图

    df.plot()

     默认索引列是横轴,值是纵轴,列是图例(多列则是多条线)

    1)可以对一列调用,此时索引是横轴,值是纵轴,列只有一个即1条折线,例如 df['列名'].plot()

     df.plot(x='A', y='B')#可以指定横轴和纵轴,此时未指定的列不参与绘图
    条形图

    df.plot.bar()

    df.plot(kind='bar')

     默认索引列是横轴,值是纵轴,列是图例(多列则是多条条形)

    1)也可以对一行数据调用,此时列是横轴,值是纵轴,无图例,例如 df.iloc[5].plot.bar()

    stacked=True#即堆积条形图,多个图例堆积成1条

    横向条形图

    df.plot.barh()

    df.plot(kind='barh')

    同条形图,只是方向是横向。  
    直方图

    df4.plot.hist()

    df.plot(kind='hist')

    默认值的值域是横轴,值的频数是纵轴,列是图例(多列则是个重叠直方图)

    1)可以对一列调用,此时索引是横轴,值是纵轴,列只有一个即1条折线,例如 df['列名'].plot.hist()

    by=#不知道是啥

    alpha=0.5

    stacked=True#即堆积直方图,多个图例堆在一个直方图上

    bins=20#分组数量,默认是10

    orientation='horizontal'#横向直方图

    cumulative=True#累积直方图

           
           
    import matplotlib.pyplot as plt
    
    fig, axs = plt.subplots(5, 2, figsize=(20, 20))
    axs[0, 0].bar(Xy.groupby('subject')['teacher_id'].count())
    axs[0, 0].set_title('subject')
    plt.show()
    
    
    
    import matplotlib.pyplot as plt
    #3.查看描述性统计
    #Xy.describe()
    #离散变量需要分组聚合,连续变量直接查看直方图
    fig, axs = plt.subplots(5, 2, figsize=(20, 20))
    Xy.groupby('a')['y'].count().plot.bar(title='a',ax = axs[0,0],color='K')
    Xy.groupby('b')['y'].count().plot.bar(title='b',ax = axs[0,1],color='K')
    Xy.groupby('c')['y'].count().plot.bar(title='c',ax = axs[1,0],color='K')
    Xy.groupby('d')['y'].count().plot.bar(title='d',ax = axs[1,1],color='K')
    Xy.groupby('e')['y'].count().plot.bar(title='e',ax = axs[2,0],color='K')
    Xy.groupby('f')['y'].count().plot.bar(title='f',ax = axs[2,1],color='K')
    Xy['g'].plot.hist(title='g',ax = axs[3,0],color='K')
    Xy['h'].plot.hist(title='h',ax = axs[3,1],color='K')
    Xy['i'].plot.hist(title='i',ax = axs[4,0],color='K')
    plt.show()
    df可视化

    四、pandas生态圈

    ——这部分介绍pandas相关的库,及相互间如何合作以达成什么目的。

    五、API目录

    ——这部分是pandas库的每个方法、类、函数等的用法,不会太怎么介绍,看情况。

    六、发展

    ——这部分暂时不知道,先不管。

    七、版本更新

    ——这部分是版本更新内容,初期不需要看,等涉及版本问题查一下即可。

    Without summary,you can't master it.
  • 相关阅读:
    《互联网时代的软件革命-saas架构设计》读书笔记
    iphone11白苹果 解决办法最简单
    idea配置(重新配置)
    力扣刷题03--无重复字符的最长字串
    力扣刷题02--两数相加
    《设计原本》读书笔记(三)
    《设计原本》读书笔记(二)
    《设计原本》读书笔记(一)
    MVC架构科技小论文
    面向服务架构及其应用
  • 原文地址:https://www.cnblogs.com/everda/p/11594522.html
Copyright © 2011-2022 走看看