Pandas-DataFrame

1、DataFrame的创建

DataFrame是一种表格型数据结构,它含有一组有序的列,每列可以是不同的值。DataFrame既有行索引,也有列索引,它可以看作是由Series组成的字典,不过这些Series公用一个索引。
DataFrame的创建有多种方式,不过最重要的还是根据dict进行创建,以及读取csv或者txt文件来创建。这里主要介绍这两种方式。

根据字段创建

>>> data = {
    'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],
    'year':[2000,2001,2002,2001,2002],
    'pop':[1.5,1.7,3.6,2.4,2.9]
}
>>> frame = pd.DataFrame(data)
>>> frame
    state  year  pop
0    Ohio  2000  1.5
1    Ohio  2001  1.7
2    Ohio  2002  3.6
3  Nevada  2001  2.4
4  Nevada  2002  2.9

DataFrame的行索引是index,列索引是columns,我们可以在创建DataFrame时指定索引的值:

>>> frame2 = pd.DataFrame(data,index=['A','B','C','D','E'],columns=['year','state','pop','debt'])
>>> frame2
   year   state  pop debt
A  2000    Ohio  1.5  NaN
B  2001    Ohio  1.7  NaN
C  2002    Ohio  3.6  NaN
D  2001  Nevada  2.4  NaN
E  2002  Nevada  2.9  NaN

使用嵌套字典也可以创建DataFrame,此时外层字典的键作为列,内层键则作为索引:

>>> pop = {'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
>>> frame3 = pd.DataFrame(pop)
>>> frame3
      Nevada  Ohio
2001     2.4   1.7
2002     2.9   3.6
2000     NaN   1.5

我们可以用index,columns,values来访问DataFrame的行索引,列索引以及数据值,数据值返回的是一个二维的ndarray
 

>>> frame2.values
array([[2000, 'Ohio', 1.5, nan],
       [2001, 'Ohio', 1.7, nan],
       [2002, 'Ohio', 3.6, nan],
       [2001, 'Nevada', 2.4, nan],
       [2002, 'Nevada', 2.9, nan]], dtype=object)

读取文件
读取文件生成DataFrame最常用的是read_csv,read_table方法。该方法中几个重要的参数如下所示:

header    默认第一行为columns,如果指定header=None,则表明没有索引行,第一行就是数据
index_col    默认作为索引的为第一列,可以设为index_col为-1,表明没有索引列
nrows    表明读取的行数
sep或delimiter    分隔符,read_csv默认是逗号,而read_table默认是制表符\t
encoding    编码格式

 data = pd.read_excel(r'C:\Users\MARS\Desktop\华东区月度工作评价\10月评价\华东区-汇总表.xlsx')

2、DataFrame轴的概念

在DataFrame的处理中经常会遇到轴的概念,这里先给大家一个直观的印象,我们所说的axis=0即表示沿着每一列或行标签\索引值向下执行方法,axis=1即表示沿着每一行或者列标签模向执行对应的方法。

3、DataFrame一些性质

索引、切片
我们可以根据列名来选取一列,返回一个Series:

>>> frame2['year']
one      2000
two      2001
three    2002
four     2001
five     2002
Name: year, dtype: int64

我们还可以选取多列或者多行:

>>> data = pd.DataFrame(np.arange(16).reshape((4,4)),index = ['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])
>>> data
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
>>> data[['two','three']]
          two  three
Ohio        1      2
Colorado    5      6
Utah        9     10
New York   13     14
#按行
>>> data[:2]
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7

当然,在选取数据的时候,我们还可以根据逻辑条件来选取:

>>> data[data['three']>5]
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
>>> data['three']>5
Ohio        False
Colorado     True
Utah         True
New York     True
Name: three, dtype: bool

pandas提供了专门的用于索引DataFrame的方法,即使用ix方法进行索引,不过ix在最新的版本中已经被废弃了,如果要是用标签,最好使用loc方法,如果使用下标,最好使用iloc方法:

>>> data.ix['Colorado',['two','three']]
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    data.ix['Colorado',['two','three']]
  File "C:\Users\MARS\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas\core\generic.py", line 5139, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'ix'
>>> data.loc['Colorado',['two','three']]
two      5
three    6
Name: Colorado, dtype: int32
>>> data.iloc[0:3,2]

Ohio         2
Colorado     6
Utah        10
Name: three, dtype: int32
>>> data.iloc[0:3,0:2]
          one  two
Ohio        0    1
Colorado    4    5
Utah        8    9

修改数据

可以使用一个标量修改DataFrame中的某一列,此时这个标量会广播到DataFrame的每一行上:

>>> frame2 = pd.DataFrame(data,index=['one','two','three','four','five'],columns=['year','state','pop','debt'])
>>> frame2
       year   state  pop debt
one    2000    Ohio  1.5  NaN
two    2001    Ohio  1.7  NaN
three  2002    Ohio  3.6  NaN
four   2001  Nevada  2.4  NaN
five   2002  Nevada  2.9  NaN
>>> frame2['debt']=16.5
>>> frame2
       year   state  pop  debt
one    2000    Ohio  1.5  16.5
two    2001    Ohio  1.7  16.5
three  2002    Ohio  3.6  16.5
four   2001  Nevada  2.4  16.5
five   2002  Nevada  2.9  16.5
>>> 

也可以使用一个列表来修改,不过要保证列表的长度与DataFrame长度相同:

>>> frame2.debt = np.arange(5)
>>> frame2

       year   state  pop  debt
one    2000    Ohio  1.5     0
two    2001    Ohio  1.7     1
three  2002    Ohio  3.6     2
four   2001  Nevada  2.4     3
five   2002  Nevada  2.9     4

可以使用一个Series,此时会根据索引进行精确匹配:

>>> val = pd.Series([-1.2,-1.5,-1.7],index=['two','four','five'])
>>> frame2['debt'] = val
>>> frame2
       year   state  pop  debt
one    2000    Ohio  1.5   NaN
two    2001    Ohio  1.7  -1.2
three  2002    Ohio  3.6   NaN
four   2001  Nevada  2.4  -1.5
five   2002  Nevada  2.9  -1.7

重新索引

使用reindex方法对DataFrame进行重新索引。对DataFrame进行重新索引,可以重新索引行,列或者两个都修改,如果只传入一个参数,则会重新索引行:

>>> frame = pd.DataFrame(np.arange(9).reshape((3,3)),index=[1,4,5],columns=['Ohio','Texas','California'])
>>> frame2 = frame.reindex([1,2,3,4,5])
>>> frame2
   Ohio  Texas  California
1   0.0    1.0         2.0
2   NaN    NaN         NaN
3   NaN    NaN         NaN
4   3.0    4.0         5.0
5   6.0    7.0         8.0
>>> states = ['Texas','Utah','California']
>>> frame.reindex(columns=states)
   Texas  Utah  California
1      1   NaN           2
4      4   NaN           5
5      7   NaN           8

填充数据只能按行填充,此时只能对行进行重新索引:

>>> frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','c','d'],columns = ['Ohio','Texas','California'])
>>> frame
   Ohio  Texas  California
a     0      1           2
c     3      4           5
d     6      7           8

#method = 'bfill':向前填充或向上填充,method = 'ffill':向后或向下填充
>>> frame.reindex(['a','b','c','d'],method = 'bfill')
   Ohio  Texas  California
a     0      1           2
b     3      4           5
c     3      4           5
d     6      7           8

丢弃指定轴上的值

可以使用drop方法丢弃指定轴上的值,不会对原DataFrame产生影响

>>> frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','c','d'],columns = ['Ohio','Texas','California'])
>>> frame
   Ohio  Texas  California
a     0      1           2
c     3      4           5
d     6      7           8
>>> frame.drop('a')
   Ohio  Texas  California
c     3      4           5
d     6      7           8
>>> frame.drop(['Ohio'],axis=1)
   Texas  California
a      1           2
c      4           5
d      7           8

算术运算

DataFrame在进行算术运算时会进行补齐,在不重叠的部分补足NA:

>>> df1 = pd.DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])

>>> df2 = pd.DataFrame(np.arange(12).reshape((4,3)),columns = list('bde'),index=['Utah','Ohio','Texas','Oregon'])

>>> df1
          b  c  d
Ohio      0  1  2
Texas     3  4  5
Colorado  6  7  8
>>> df2
        b   d   e
Utah    0   1   2
Ohio    3   4   5
Texas   6   7   8
Oregon  9  10  11

#任意一方为空则结果为空
>>> df1 + df2
            b   c     d   e
Colorado  NaN NaN   NaN NaN
Ohio      3.0 NaN   6.0 NaN
Oregon    NaN NaN   NaN NaN
Texas     9.0 NaN  12.0 NaN
Utah      NaN NaN   NaN NaN

可以使用fill_value方法填充NA数据,不过两个df中都为NA的数据,该方法不会填充:

#对df2进行填充,未对df1进行填充
>>> df1.add(df2,fill_value=0)
            b    c     d     e
Colorado  6.0  7.0   8.0   NaN
Ohio      3.0  1.0   6.0   5.0
Oregon    9.0  NaN  10.0  11.0
Texas     9.0  4.0  12.0   8.0
Utah      0.0  NaN   1.0   2.0

函数应用和映射

numpy的元素级数组方法,也可以用于操作Pandas对象:

>>> frame = pd.DataFrame(np.arange(9).reshape(3,3),columns=list('bcd'),index=['ohio','Texas','Colora0'])
>>> frame
         b  c  d
ohio     0  1  2
Texas    3  4  5
Colora0  6  7  8

另一个常见的操作是,将函数应用到由各列或行所形成的一维数组上。DataFrame的apply方法即可实现此功能。

>>> frame = pd.DataFrame(np.arange(9).reshape(3,3),columns=list('bcd'),index=['ohio','Texas','Colora0'])
>>> frame
         b  c  d
ohio     0  1  2
Texas    3  4  5
Colora0  6  7  8
>>> f = lambda x:x.max() - x.min()
>>> frame.apply(f)
b    6
c    6
d    6
dtype: int64
>>> frame.apply(f,axis=1)
ohio       2
Texas      2
Colora0    2
dtype: int64
>>> def f(x):
    return pd.Series([x.min(),x.max()],index=['min','max'])

>>> frame.apply(f)
     b  c  d
min  0  1  2
max  6  7  8
>>> frame.apply(f,axis=1)
         min  max
ohio       0    2
Texas      3    5
Colora0    6    8
>>> 

元素级的Python函数也是可以用的,使用applymap方法:

>>> format = lambda x:'%.2f'%x

>>> frame.applymap(format)
            b     c     d
ohio     0.00  1.00  2.00
Texas    3.00  4.00  5.00
Colora0  6.00  7.00  8.00

排序和排名

对于DataFrame,sort_index可以根据任意轴的索引进行排序,并指定升序降序

>>> frame = pd.DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])
>>> frame
       d  a  b  c
three  0  1  2  3
one    4  5  6  7
>>> frame.sort_index()
       d  a  b  c
one    4  5  6  7
three  0  1  2  3

#1代表从第二列,ascending=False代表降序
>>> frame.sort_index(1,ascending=False)
       d  c  b  a
three  0  3  2  1
one    4  7  6  5

DataFrame也可以按照值进行排序:

>>> frame.sort_values(by=['a','b'])
       d  a  b  c
three  0  1  2  3
one    4  5  6  7

汇总和计算描述统计
DataFrame中的实现了sum、mean、max等方法,我们可以指定进行汇总统计的轴,同时,也可以使用describe函数查看基本所有的统计项

>>> df = pd.DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],index=['a','b','c','d'],columns=['one','two'])

>>> df
    one  two
a  1.40  NaN
b  7.10 -4.5
c   NaN  NaN
d  0.75 -1.3

#Na会被自动排除,可以使用skipna选项来禁用该功能
>>> df.sum(axis=1)
a    1.40
b    2.60
c    0.00
d   -0.55
dtype: float64

>>> df.mean(axis=1,skipna=False)
a      NaN
b    1.300
c      NaN
d   -0.275
dtype: float64

#idxmax返回间接统计,是达到最大值的索引
>>> df.idxmax()
one    b
two    d
dtype: object
#describe返回的是DataFrame的汇总统计
#非数值型的与数值型的统计返回结果不同
>>> df.describe()
            one       two
count  3.000000  2.000000
mean   3.083333 -2.900000
std    3.493685  2.262742
min    0.750000 -4.500000
25%    1.075000 -3.700000
50%    1.400000 -2.900000
75%    4.250000 -2.100000
max    7.100000 -1.300000

DataFrame也实现了corr和cov方法来计算一个DataFrame的相关系数矩阵和协方差矩阵,同时DataFrame也可以与Series求解相关系数。

>>> frame1 = pd.DataFrame(np.random.randn(3,3),index=list('abc'),columns=list('abc'))

>>> frame1.corr
<bound method DataFrame.corr of           a         b         c
a -0.904678  2.107092  0.656929
b  0.126742 -1.373721  0.462393
c -0.582205 -0.602093  0.736974>
>>> frame1.cov()
          a         b         c
a  0.278404 -0.835143 -0.061583
b -0.835143  3.341859  0.112027
c -0.061583  0.112027  0.019941

#corrwith用于计算每一列与Series的相关系数
>>> frame1.corrwith(frame1['a'])
a    1.000000
b   -0.865824
c   -0.826516
dtype: float64

处理缺失数据

Pandas中缺失值相关的方法主要有以下三个:
isnull方法用于判断数据是否为空数据;
fillna方法用于填补缺失数据;
dropna方法用于舍弃缺失数据。
上面两个方法返回一个新的Series或者DataFrame,对原数据没有影响,如果想在原数据上进行直接修改,使用inplace参数:

>>> data = pd.DataFrame([[1,6.5,3],[1,np.nan,np.nan],[np.nan,np.nan,np.nan],[np.nan,6.5,3]],index=['A','B','C','D'], columns=['ONE','TWO','THREE'])
>>> data
   ONE  TWO  THREE
A  1.0  6.5    3.0
B  1.0  NaN    NaN
C  NaN  NaN    NaN
D  NaN  6.5    3.0
>>> data.dropna()
   ONE  TWO  THREE
A  1.0  6.5    3.0

对DataFrame来说,dropna方法如果发现缺失值,就会进行整行删除,不过可以指定删除的方式,how=all,是当整行全是na的时候才进行删除,同时还可以指定删除的轴。
 

>>> data.dropna(how='all',axis=1,inplace=True)
>>> data
   ONE  TWO  THREE
A  1.0  6.5    3.0
B  1.0  NaN    NaN
C  NaN  NaN    NaN
D  NaN  6.5    3.0

DataFrame填充缺失值可以统一填充,也可以按列填充,或者指定一种填充方式:

#method = 'bfill':向前填充或向上填充,method = 'ffill':向后或向下填充
>>> data.fillna({1:2,2:3})
   ONE  TWO  THREE
A  1.0  6.5    3.0
B  1.0  NaN    NaN
C  NaN  NaN    NaN
D  NaN  6.5    3.0
>>> data.fillna(method='ffill')
   ONE  TWO  THREE
A  1.0  6.5    3.0
B  1.0  6.5    3.0
C  1.0  6.5    3.0
D  1.0  6.5    3.0

函数形式:fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)

参数:

value:用于填充的空值的值。

method: {'backfill', 'bfill', 'pad', 'ffill', None}, default None。定义了填充空值的方法, pad / ffill表示用前面行/列的值,填充当前行/列的空值, backfill / bfill表示用后面行/列的值,填充当前行/列的空值。

axis:轴。0或'index',表示按行删除;1或'columns',表示按列删除。

inplace:是否原地替换。布尔值,默认为False。如果为True,则在原DataFrame上进行操作,返回值为None。

limit:int, default None。如果method被指定,对于连续的空值,这段连续区域,最多填充前 limit 个空值(如果存在多段连续区域,每段最多填充前 limit 个空值)。如果method未被指定, 在该axis下,最多填充前 limit 个空值(不论空值连续区间是否间断)

downcast:dict, default is None,字典中的项为,为类型向下转换规则。或者为字符串“infer”,此时会在合适的等价类型之间进行向下转换,比如float64 to int64 if possible。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值