利用python进行数据分析(重点、易忘点)---第五章Pandas基础学习

之前看的pandas的教材和课程里,内容参差不齐,实际使用很少的方法的内容有点多,导致很乱而且记不住那么多,这个帖子尽量用最少的文字,最精炼的语言来总结比较实用的方法,内容主要来源于《利用python进行数据分析》。

1.创建Series

直接给列表,加index。

obj = pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])

也可以用字典

sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}

obj3 = pd.Series(sdata)

2.创建DataFrame

用最基础的方式,列表嵌套字典,注意把index放在字典外部,或者columns。

df= pd.DataFrame( {'first': ['kevin', 'lou', 'ian'], 
'last': ['durant', 'reed', 'brown']}, index=['3', '4', '5'] )

下面用numpy的array数组构建DataFrame,如果要加每行、每列的指定索引可以指定index、columns,array数组没有指定索引。

frame = pd.DataFrame(np.arange(9).reshape(3,3),
index=['a','b','c'],columns=['h','i','j'])

 3.DataFrame取行或列

非常重要:python中注意区分数字和字符,比如loc的使用,iloc的使用不在讨论中,iloc只能放数字(序号)。

DataFrame取列:用df['列名']或df.列名,用前者;

DataFrame取行:用loc[ ]或iloc[ ]。

tip:如果index和columns设置成数字例如1,2等,取行和取列应该为df[数字]和loc[数字],注意没有引号,如果设置成"0"、"1"(字符)的话,那就要在df[数字]中加上引号。

然后是loc和iloc的一些嵌套使用,类似这样:

data.loc['Colorado', ['two', 'three']]

data.iloc[2, [3, 0, 1]]

值得一提的是(很重要) :相对于iloc,loc的取值不像传统的python列表的选取那样,使用“:”的时候会忽略掉“:”后的那个元素,而是会取到那个值,而iloc依然是和python列表的特性一样。

a = [0,1,2,3,4,5]

a[:5]  #返回[0, 1, 2, 3, 4]

ser = pd.Series(np.arange(3.))

In [144]: ser
Out[144]: 
0    0.0
1    1.0
2    2.0
dtype: float64

In [147]: ser[:1]
Out[147]: 
0    0.0
dtype: float64

In [148]: ser.loc[:1]
Out[148]: 
0    0.0
1    1.0
dtype: float64

In [149]: ser.iloc[:1]
Out[149]: 
0    0.0
dtype: float64

4.使用方法3对DataFrame进行取列或加列后操作

DataFrame和Series是带有索引的,如果想修改或增加它们的数据,索引应该要对上。(如果增加的数据是numpy的array或者其他没有索引的数据,那么数据个数能对的上就行。)

# numpy的array和单纯一个数字是没有索引的,可以直接加上去。

frame2['debt'] = np.arange(6.)

frame2['debt'] = 16.5

 # frame2.state == 'Ohio'得到是一个与frame2相同索引的布尔值Series,所以能够顺利加上列。

frame2['eastern'] = frame2.state == 'Ohio'

#再比如,这个Val(Series)的索引相对于frame2的索引不完全,只有三个索引对应的3个值,索引最后结果只有3个数据匹配上增加,其他的用NaN填充。

In [58]: val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
In [59]: frame2['debt'] = val
In [60]: frame2
Out[60]: 
       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
six    2003  Nevada  3.2   NaN

这就会延申到算术运算和数据对齐部分。

5. 数据(索引)对齐后进行算术运算

数据对齐的规则在上一条已经大致说清楚了。这里的算术运算也是类似的,要求数据(索引)对齐。

算术运算的方法:可以用符号"+-*/",也可以用方法add、sub、mul、div。

Seires的算术运算比较简单,毕竟只有一维索引,要求索引对齐;DataFrame需要二维索引都对齐。不对齐的话和上面一样会出现NaN的数据。为了避免这种NaN,可以用方法“fill_value”填充值自动填充。

df1.add(df2, fill_value=0)

然后是DataFrame与Series之间的运算,依然要求数据对齐,重要的是横向还是纵向算术运算。

先用numpy的array来举个例子。arr是个3*4的array,用arr[0]提取第一行(1*4的array),然后用arr减去arr[0],是把arr的每一行都减去arr[1]这个array。

In [175]: arr = np.arange(12.).reshape((3, 4))
In [176]: arr
Out[176]: 
array([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.]])
In [177]: arr[0]
Out[177]: array([ 0.,  1.,  2.,  3.])
In [178]: arr - arr[0]
Out[178]: 
array([[ 0.,  0.,  0.,  0.],
       [ 4.,  4.,  4.,  4.],
       [ 8.,  8.,  8.,  8.]])

进而引申到DataFrame与Series的运算(前提是数据对齐),也是默认对DataFrame的每行分别减去Series。

In [179]: frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
   .....:                      columns=list('bde'),
   .....:                      index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [180]: series = frame.iloc[0]
In [181]: frame
Out[181]: 
          b     d     e
Utah    0.0   1.0   2.0
Ohio    3.0   4.0   5.0
Texas   6.0   7.0   8.0
Oregon  9.0  10.0  11.0
In [182]: series
Out[182]: 
b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64

In [183]: frame - series
Out[183]: 
          b    d    e
Utah    0.0  0.0  0.0
Ohio    3.0  3.0  3.0
Texas   6.0  6.0  6.0
Oregon  9.0  9.0  9.0

如果DataFrame与Series的运算,要求对DataFrame的每列与Series进行算术运算,要结合axis的使用。###(这个地方的axis不用默认为1或‘columns’,可以改成0或‘index’在每列层次上进行运算)###这里发现axis默认竟然不是0?于是gpt了一下发现,关于 axis 默认值 的问题,答案是:具体情况具体分析,因为 默认的行为取决于参与运算的对象类型和索引结构

比如这里DataFrame与Series的运算的例子。

默认行为依赖于 Series 的索引

  • 如果 Series 的索引与 DataFrame 的行索引对齐,则默认 axis=0
  • 如果 Series 的索引与 DataFrame 的列索引对齐,则默认 axis=1
In [186]: series3 = frame['d']
In [187]: frame
Out[187]: 
          b     d     e
Utah    0.0   1.0   2.0
Ohio    3.0   4.0   5.0
Texas   6.0   7.0   8.0
Oregon  9.0  10.0  11.0
In [188]: series3
Out[188]: 
Utah       1.0
Ohio       4.0
Texas      7.0
Oregon    10.0
Name: d, dtype: float64
In [189]: frame.sub(series3, axis='index')
Out[189]: 
          b    d    e
Utah   -1.0  0.0  1.0
Ohio   -1.0  0.0  1.0
Texas  -1.0  0.0  1.0
Oregon -1.0  0.0  1.0

### 要特别注意加减乘除和sum()/average()等这些函数关于axis的使用 ###

6. “重新提取”和修改索引

Series、DataFrame(配合参数axis和0或1)可以用reindex,“重新提取”列名或行名,如果不加参数默认提取index(Series只有index),下面obj没有索引“e”对应的值,所以返回NaN。

In [91]: obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
In [93]: obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
In [94]: obj2
Out[94]: 
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN

下面df使用了axis=1,就是重新提取列名了(columns)

In [94]: df= pd.DataFrame(
    {'first': ['kevin', 'lou', 'ian'], 'last': ['durant', 'reed', 'brown']},
    index=[3,4,5])

Out[94]: df.reindex(['first','third'],axis=1)

    first	third
3	kevin	NaN
4	lou	    NaN
5	ian    	NaN
    

修改索引就是直接对索引进行修改。 用df.index、df.columns来修改。

7.丢弃指定轴上的项

涉及到del、drop的使用,主要是drop

对于Series,直接drop掉想要丢弃的索引及涉及的数据们。

In [105]: obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])

In [107]: new_obj = obj.drop(['d', 'c'])

对于DataFrame,当然也可以用drop方法,但是要注意依然默认axis=0(index),即删除行。

In [110]: data = pd.DataFrame(np.arange(16).reshape((4, 4)),
   .....:                     index=['Ohio', 'Colorado', 'Utah', 'New York'],
   .....:                     columns=['one', 'two', 'three', 'four'])

In [112]: data.drop(['Colorado', 'Ohio'])
Out[112]: 
          one  two  three  four
Utah        8    9     10    11
New York   12   13     14    15

要删除列,让axis=1(columns)。

In [114]: data.drop(['two', 'four'], axis='columns')
Out[114]: 
          one  three
Ohio        0      2
Colorado    4      6
Utah        8     10
New York   12     14

顺带提一下del在DataFrame的运用,del用于“彻底”删除DataFrame的某列(不能删除行),相比于del的删除,drop的删除像是临时性的,临时返回一个结果对象,不会改变DataFrame本身,通常把临时修改的结果赋给某个新变量,如果想实现“彻底”删除某一行/列,可结合inplace=True选项。(很多方法在这方面和drop都是类似的,结合inplace=True实现“彻底”执行,可以就地修改对象,不会返回新的对象,这是书上原话)

del frame2['eastern']

In [115]: obj.drop('c', inplace=True)
In [116]: obj
Out[116]: 
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

 8.排序

排序涉及到两个方法,sort_values(值)方法和sort_index(索引)方法。

对于Series,直接在对象后面使用方法就行。

obj.sort_index()
obj.sort_values()

对于DataFrame,先讨论sort_index。需要注意一些参数。首先依然是axis,不设置axis默认为0(index),也可以设置axis=1(columns),对列索引排序。

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

数据默认是按升序排序的,但也可以降序排序,设置参数ascending=False

In [206]: frame.sort_index(axis=1, ascending=False)
Out[206]: 
       d  c  b  a
three  0  3  2  1
one    4  7  6  5

 下面是sort_values的讨论。首先要明确在排序时,任何缺失值默认都会被放到Series的末尾。

刚才讲的axisascending=False在sort_values依旧适用。然后是一些额外的补充by参数,需要选择sort_values(by=‘列名’)或者sort_values(by='行名',axis=1),by也可以放行/列名列表,按优先级进行排序。

frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})

In [212]: frame
Out[212]: 
   a  b
0  0  4
1  1  7
2  0 -3
3  1  2

In [214]: frame.sort_values(by=['a', 'b'])
Out[214]: 
   a  b
2  0 -3
0  0  4
3  1  2
1  1  7

In [215]: frame.sort_values(by=2,axis=1)
Out[215]:
   b  a
0  4  0
1  7  1
2 -3  0
3  2  1

 9.汇总和计算描述统计

一些常用count、sum、mean、cumsum等描述汇总统计等,不再赘述。

DataFrame的corr和cov方法将以DataFrame的形式分别返回完整的相关系数或协方差矩阵:

# returns有四列数据AAPL、GOOG、IBM、MSFT

In [247]: returns.corr()
Out[247]: 
          AAPL      GOOG       IBM      MSFT
AAPL  1.000000  0.407919  0.386817  0.389695
GOOG  0.407919  1.000000  0.405099  0.465919
IBM   0.386817  0.405099  1.000000  0.499764
MSFT  0.389695  0.465919  0.499764  1.000000
In [248]: returns.cov()
Out[248]: 
          AAPL      GOOG       IBM      MSFT
AAPL  0.000277  0.000107  0.000078  0.000095
GOOG  0.000107  0.000251  0.000078  0.000108
IBM   0.000078  0.000078  0.000146  0.000089
MSFT  0.000095  0.000108  0.000089  0.000215

10.唯一值、值计数以及成员资格

下面更多是对Series对象使用的方法。

可以用unique方法返回唯一值:

In [251]: obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])

In [252]: uniques = obj.unique()
In [253]: uniques
Out[253]: array(['c', 'a', 'd', 'b'], dtype=object)

value_counts()方法对Series里的值计数并倒序返回计数值排序。(注意单词拼写,以及这里value没有复数,区分之前的sort_values

In [254]: obj.value_counts()
Out[254]: 
c    3
a    3
b    2
d    1
dtype: int64

然后是一个isin方法,可以判断Series里面的元素是否在isin的列表里,返回一个布尔值Series。可以把这个布尔值Series结合之前的汇总描述统计方法配合使用。

In [256]: obj
Out[256]: 
0    c
1    a
2    d
3    a
4    a
5    b
dtype: object
In [257]: mask = obj.isin(['b', 'c'])
In [258]: mask
Out[258]: 
0     True
1    False
2    False
3    False
4    False
5     True
dtype: bool

In [259]: obj[mask]
Out[259]: 
0    c
5    b
dtype: object

最后带一句:关于axis的选择对于DataFrame确实比较复杂,且涉及大部分方法,可以不用死记硬背,使用方法时,可以进行一些试错尝试(使用副本等其他方法避免对原数据操作,以免造成不可逆转的操作),来选择正确的axis参数。

你可能感兴趣的:(利用python进行数据分析,pandas)