我爱编程

pandas

2018-06-21  本文已影响293人  喔蕾喔蕾喔蕾蕾蕾
参考资料:

Pandas 文档

开始

安装 pip install pandas
使用前需导入模块:import pandas as pd
pandas的底层基础是numpy,Series的很多基本操作跟numpy很像,但也有以下的区别:
1、可以为 Pandas Series 中的每个元素分配索引标签,标签可以指定任何名称
2、Pandas Series 可以存储不同类型的数据

使用

Pandas模块的数据结构主要有两:1、Series ;2、DataFrame

Series

Series结构是基于NumPy的ndarray结构,是一个一维的标签矩阵(个人小感慨,如果说numpy的很像列表,那我觉得pandas很像字典)

(1)pd.Series([list],index=[list])
以list为参数,参数为一list; index为可选参数,若不填则默认index从0开始;若添则index长度与value长度相等

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

(2)pd.Series({dict})
以一字典结构为参数

s=pd.Series({'a':3,'b':4,'c':5,'f':6,'e':8})

(1)类似numpy的方式
s[index] or s[[index的list]] or s[start:end]
s[bool表达式]

取值操作类似numpy,只是因为Series室友自定义标签的,不仅可以使用位置(就是0,1,2类似的值)来查询,还能使用标签索引来进行查询(注意到了吗,在Series里,标签索引才是索引,原来的0,1,2被称为了位置),切片和布尔表达式方式与numpy相同,当取不连续的多个值时一样也可以一list为参数。

from pandas import Series
import pandas as pd
series1 = Series([10, 20, 30, 40], index=list('abcd'))
# 通过位置查询
series1[2]
# 通过标签索引查询
series1['b']
# 查询多个元素
series1[[0, 2, 3]]
series1[['a', 'c', 'd']]
# 切片
series1[1:3]
series1['b':'d']
# 布尔索引
series1[series1 > 20]

(2)类似字典的方式
s.index
s.values

from pandas import Series
import pandas as pd
series1 = Series([10, 20, 30, 40], index=list('abcd'))
series1.index#输出abcd
series1.values#输出10,20,30,40

(3)in判断
跟字典一样,可以用in来判断某个标签是否在Series中

groceries = pd.Series(data = [30, 6, 'Yes', 'No'], index = ['eggs', 'apples', 'milk', 'bread'])
# We check whether bananas is a food item (an index) in Groceries
x = 'bananas' in groceries
# We check whether bread is a food item (an index) in Groceries
y = 'bread' in groceries
# We print the results
print('Is bananas an index label in Groceries:', x)
print('Is bread an index label in Groceries:', y)
#输出
Is bananas an index label in Groceries: False
Is bread an index label in Groceries: True

(4).loc ,.iloc和ix
loc 在index的标签上进行索引,范围包括start和end.
iloc 在index的位置上进行索引,不包括end.
ix 先在index的标签上索引,索引不到就在index的位置上索引(如果index非全整数),不包括end.

>>> data = pd.Series(np.arange(10), index=[49,48,47,46,45, 1, 2, 3, 4, 5])
>>> data
49    0
48    1
47    2
46    3
45    4
1     5
2     6
3     7
4     8
5     9
dtype: int64
>>> data.iloc[:6]
49    0
48    1
47    2
46    3
45    4
1     5
dtype: int64
>>> data.loc[:6]
KeyError: 6
>>> data.ix[:6] #因为index里面不包含标签6,index都是整数
KeyError: 6
>>> data= pd.Series(np.arange(10), index=['a','b','c','d','e', 1, 2, 3, 4, 5])
>>> data
a    0
b    1
c    2
d    3
e    4
1    5
2    6
3    7
4    8
5    9
dtype: int64
>>> data.ix[:6]
a    0
b    1
c    2
d    3
e    4
1    5
dtype: int64
>>> data.loc[:6]
TypeError: cannot do slice indexing
series1 = Series([10, 20, 30, 40], index=list('abcd'))

# 删除元素返回副本
series1.drop('c')
series1.drop(['a', 'd'])

# 删除源数据中的元素
series1.pop('d')

(1)正常的+-*/,像numpy一样,所有数据进行运算。
注意,不会改变原始数据,只会返回一个运算后的副本
(2)使用numpy数学函数,比如np.exp(),np.power(),np.sqrt()等等
注意,不会改变原始数据,只会返回一个运算后的副本
(3)单个索引运算跟上面的取值并赋值操作一样的。就是等号
类似上面的例子中,让series1['a']+2这样

DataFrame

Pandas DataFrames 是具有带标签的行和列的二维数据结构
先带一下课程内容:

取值:

#创建如视频中的一样
#取值方式如下:
#df名称[[列名]]来得到某列数据
print('How many bikes are in each store:\n', store_items[['bikes']])
#df名称[[列名,列名]]来得到多列的数据
print('How many bikes and pants are in each store:\n', store_items[['bikes', 'pants']])
#df.loc[[行名]]来得到某行的数据,一定要注意,得某行一定要用.loc来得
同理,df.loc[[行名,行名]]来得到多行
print('What items are in Store 1:\n', store_items.loc[['store 1']])
#df[列名][行名]来得到某确定行列位置的值
print('How many bikes are in Store 2:', store_items['bikes']['store 2'])

赋值:
以上的取值方法加上赋值运算符就能进行赋值运算。

new_items = [{'bikes': 20, 'pants': 30, 'watches': 35, 'glasses': 4}]
new_store = pd.DataFrame(new_items, index = ['store 3'])
store_items = store_items.append(new_store)

方法二,df.insert方法
dataframe.insert(loc,label,data) 方法将新列(具有给定列标签和给定数据)插入 dataframe 的 loc 位置。

store_items.insert(4, 'shoes', [8,5,0])
def drop(self, labels=None, axis=0, index=None, columns=None,level=None, inplace=False, errors='raise')

可以用axis来控制删除行还是列,也可以使用index和columns来控制行列,inplace还是老样子,是否修改原数据,level是说有多重标签的情况下,哪一级的标签会去做删除动作。
例子

        >>> df = pd.DataFrame(np.arange(12).reshape(3,4),
        ...                   columns=['A', 'B', 'C', 'D'])
        >>> df
           A  B   C   D
        0  0  1   2   3
        1  4  5   6   7
        2  8  9  10  11
        Drop columns
        >>> df.drop(['B', 'C'], axis=1)
           A   D
        0  0   3
        1  4   7
        2  8  11
        >>> df.drop(columns=['B', 'C'])
           A   D
        0  0   3
        1  4   7
        2  8  11
        Drop a row by index
        >>> df.drop([0, 1])
           A  B   C   D
        2  8  9  10  11
        Drop columns and/or rows of MultiIndex DataFrame
        >>> midx = pd.MultiIndex(levels=[['lama', 'cow', 'falcon'],
        ...                              ['speed', 'weight', 'length']],
        ...                      labels=[[0, 0, 0, 1, 1, 1, 2, 2, 2],
        ...                              [0, 1, 2, 0, 1, 2, 0, 1, 2]])
        >>> df = pd.DataFrame(index=midx, columns=['big', 'small'],
        ...                   data=[[45, 30], [200, 100], [1.5, 1], [30, 20],
        ...                         [250, 150], [1.5, 0.8], [320, 250],
        ...                         [1, 0.8], [0.3,0.2]])
        >>> df
                        big     small
        lama    speed   45.0    30.0
                weight  200.0   100.0
                length  1.5     1.0
        cow     speed   30.0    20.0
                weight  250.0   150.0
                length  1.5     0.8
        falcon  speed   320.0   250.0
                weight  1.0     0.8
                length  0.3     0.2
        >>> df.drop(index='cow', columns='small')
                        big
        lama    speed   45.0
                weight  200.0
                length  1.5
        falcon  speed   320.0
                weight  1.0
                length  0.3
        >>> df.drop(index='length', level=1)
                        big     small
        lama    speed   45.0    30.0
                weight  200.0   100.0
        cow     speed   30.0    20.0
                weight  250.0   150.0
        falcon  speed   320.0   250.0
                weight  1.0     0.8

方法二,df.pop方法
pop方法只允许删除列,并且是直接修改了原df数据

>>> df = pd.DataFrame([('falcon', 'bird',    389.0),
...                    ('parrot', 'bird',     24.0),
...                    ('lion',   'mammal',   80.5),
...                    ('monkey', 'mammal', np.nan)],
...                   columns=('name', 'class', 'max_speed'))
>>> df
     name   class  max_speed
0  falcon    bird      389.0
1  parrot    bird       24.0
2    lion  mammal       80.5
3  monkey  mammal        NaN
>>> df.pop('class')
0      bird
1      bird
2    mammal
3    mammal
Name: class, dtype: object
>>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
>>> df.rename(index=str, columns={"A": "a", "B": "c"})
   a  c
0  1  4
1  2  5
2  3  6
>>> df.rename({1: 2, 2: 4}, axis='index')
   A  B
0  1  4
2  2  5
4  3  6
>>> df.rename(str.lower, axis='columns')
   a  b
0  1  4
1  2  5
2  3  6

方法二:
set_index
DataFrame可以通过set_index方法,可以设置单索引和复合索引。
DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)
append添加新索引,drop为False,inplace为True时,索引将会还原为列

In [307]: data
Out[307]: 
     a    b  c    d
0  bar  one  z  1.0
1  bar  two  y  2.0
2  foo  one  x  3.0
3  foo  two  w  4.0

In [308]: indexed1 = data.set_index('c')

In [309]: indexed1
Out[309]: 
     a    b    d
c               
z  bar  one  1.0
y  bar  two  2.0
x  foo  one  3.0
w  foo  two  4.0

In [310]: indexed2 = data.set_index(['a', 'b'])

In [311]: indexed2
Out[311]: 
         c    d
a   b          
bar one  z  1.0
    two  y  2.0
foo one  x  3.0
    two  w  4.0

方法三
reset_index
reset_index可以还原索引,从新变为默认的整型索引
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=”)
level控制了具体要还原的那个等级的索引
drop为False则索引列会被还原为普通列,否则会丢失

In [318]: data
Out[318]: 
         c    d
a   b          
bar one  z  1.0
    two  y  2.0
foo one  x  3.0
    two  w  4.0

In [319]: data.reset_index()
Out[319]: 
     a    b  c    d
0  bar  one  z  1.0
1  bar  two  y  2.0
2  foo  one  x  3.0
3  foo  two  w  4.0

方法二:
df.count()
DataFrame.count(axis=0, level=None, numeric_only=False)
使用count方法,也能得到哪一行或者那一列是否有空值

>>> df = pd.DataFrame({"Person":
...                    ["John", "Myla", None, "John", "Myla"],
...                    "Age": [24., np.nan, 21., 33, 26],
...                    "Single": [False, True, True, True, False]})
>>> df
   Person   Age  Single
0    John  24.0   False
1    Myla   NaN    True
2    None  21.0    True
3    John  33.0    True
4    Myla  26.0   False
>>> df.count()
Person    4
Age       4
Single    5
dtype: int64
>>> df.count(axis='columns')
0    3
1    2
2    2
3    3
4    3
dtype: int64
>>> df.set_index(["Person", "Single"]).count(level="Person")
        Age
Person
John      2
Myla      1

方法三,
df.dropna和df.fillna
(1).dropna方法,对于Serial对象,丢弃带有NAN的所有项,对于DataFrame对象,默认丢弃带有NAN的行

#seriea:
In [152]: data=pd.Series([1,np.nan,5,np.nan])

In [153]: data
Out[153]:
0    1.0
1    NaN
2    5.0
3    NaN
dtype: float64

In [154]: data.dropna()
Out[154]:
0    1.0
2    5.0
dtype: float64
#dataframe
In [19]: data=pd.DataFrame([[1,5,9,np.nan],[np.nan,3,7,np.nan],[6,np.nan,2,np.nan]
    ...: ,[np.nan,np.nan,np.nan,np.nan],[1,2,3,np.nan]])

In [20]: data
Out[20]:
     0    1    2   3
0  1.0  5.0  9.0 NaN
1  NaN  3.0  7.0 NaN
2  6.0  NaN  2.0 NaN
3  NaN  NaN  NaN NaN
4  1.0  2.0  3.0 NaN
#默认删除了所有带nan的行
In [21]: data.dropna()
Out[21]:
Empty DataFrame
Columns: [0, 1, 2, 3]
Index: []
#删除列的nan,how = all是说所有都是nan删除
In [23]: data.dropna(axis=1,how='all')
Out[23]:
     0    1    2
0  1.0  5.0  9.0
1  NaN  3.0  7.0
2  6.0  NaN  2.0
3  NaN  NaN  NaN
4  1.0  2.0  3.0
#只保留至少有3个非NAN值的行
In [24]: data.dropna(thresh=3)
Out[24]:
     0    1    2   3
0  1.0  5.0  9.0 NaN
4  1.0  2.0  3.0 NaN

(2).fillna方法,以常数替换NAN值
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)

>>> df = pd.DataFrame([[np.nan, 2, np.nan, 0],
...                    [3, 4, np.nan, 1],
...                    [np.nan, np.nan, np.nan, 5],
...                    [np.nan, 3, np.nan, 4]],
...                    columns=list('ABCD'))
>>> df
     A    B   C  D
0  NaN  2.0 NaN  0
1  3.0  4.0 NaN  1
2  NaN  NaN NaN  5
3  NaN  3.0 NaN  4
#全部填充常数
>>> df.fillna(0)
    A   B   C   D
0   0.0 2.0 0.0 0
1   3.0 4.0 0.0 1
2   0.0 0.0 0.0 5
3   0.0 3.0 0.0 4
#设定填充要求
>>> values = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
>>> df.fillna(value=values)
    A   B   C   D
0   0.0 2.0 2.0 0
1   3.0 4.0 2.0 1
2   0.0 1.0 2.0 5
3   0.0 3.0 2.0 4
#limit限制每列填充几个
>>> df.fillna(value=values, limit=1)
    A   B   C   D
0   0.0 2.0 2.0 0
1   3.0 4.0 NaN 1
2   NaN 1.0 NaN 5
3   NaN 3.0 NaN 4

方法四:
interpolate()方法
DataFrame.interpolate(method='linear', axis=0, limit=None, inplace=False, limit_direction='forward', limit_area=None, downcast=None, **kwargs)
通过 linear 插值使用沿着给定 axis 的值替换 NaN 值。

>>> s = pd.Series([0, 1, np.nan, 3])
>>> s.interpolate()
0    0
1    1
2    2
3    3
dtype: float64
#举例:
In [13]: df2 = pd.DataFrame({'X' : ['B', 'B', 'A', 'A'], 'Y' : [1, 2, 3, 4]})

In [14]: df2.groupby(['X']).sum()
Out[14]: 
   Y
X   
A  7
B  3

In [15]: df2.groupby(['X'], sort=False).sum()
Out[15]: 
   Y
X   
B  3
A  7

In [16]: df3 = pd.DataFrame({'X' : ['A', 'B', 'A', 'B'], 'Y' : [1, 4, 3, 2]})

In [17]: df3.groupby(['X']).get_group('A')
Out[17]: 
   X  Y
0  A  1
2  A  3

In [18]: df3.groupby(['X']).get_group('B')
Out[18]: 
   X  Y
1  B  4
3  B  2






下面是一个总结性的datafram常用方法:
一、生成数据表
1、首先导入pandas库,一般都会用到numpy库,所以我们先导入备用:

import numpy as np
import pandas as pd

2、导入CSV或者xlsx文件:

df = pd.DataFrame(pd.read_csv('name.csv',header=1))
df = pd.DataFrame(pd.read_excel('name.xlsx'))

3、用pandas创建数据表:

df = pd.DataFrame({"id":[1001,1002,1003,1004,1005,1006], 
 "date":pd.date_range('20130102', periods=6),
  "city":['Beijing ', 'SH', ' guangzhou ', 'Shenzhen', 'shanghai', 'BEIJING '],
 "age":[23,44,54,32,34,32],
 "category":['100-A','100-B','110-A','110-C','210-A','130-F'],
  "price":[1200,np.nan,2133,5433,np.nan,4432]},
  columns =['id','date','city','category','age','price'])

2、数据表信息查看
1、维度查看:

df.shape

2、数据表基本信息(维度、列名称、数据格式、所占空间等):

df.info()

3、每一列数据的格式:

df.dtypes

4、某一列格式:

df['B'].dtype

5、空值:

df.isnull()

6、查看某一列空值:

df.isnull()

7、查看某一列的唯一值:

df['B'].unique()

8、查看数据表的值:

df.values 

9、查看列名称:

df.columns

10、查看前10行数据、后10行数据:

df.head() #默认前10行数据
df.tail()    #默认后10 行数据

三、数据表清洗
1、用数字0填充空值:

df.fillna(value=0)

2、使用列prince的均值对NA进行填充:

df['prince'].fillna(df['prince'].mean())

3、清楚city字段的字符空格:

df['city']=df['city'].map(str.strip)

4、大小写转换:

df['city']=df['city'].str.lower()

5、更改数据格式:

df['price'].astype('int')       

6、更改列名称:

df.rename(columns={'category': 'category-size'}) 

7、删除后出现的重复值:

df['city'].drop_duplicates()

8、删除先出现的重复值:

df['city'].drop_duplicates(keep='last')

9、数据替换:

df['city'].replace('sh', 'shanghai')

四、数据预处理

df1=pd.DataFrame({"id":[1001,1002,1003,1004,1005,1006,1007,1008], 
"gender":['male','female','male','female','male','female','male','female'],
"pay":['Y','N','Y','Y','N','Y','N','Y',],
"m-point":[10,12,20,40,40,40,30,20]})

1、数据表合并

df_inner=pd.merge(df,df1,how='inner')  # 匹配合并,交集
df_left=pd.merge(df,df1,how='left')        #
df_right=pd.merge(df,df1,how='right')
df_outer=pd.merge(df,df1,how='outer')  #并集

2、设置索引列

df_inner.set_index('id')

3、按照特定列的值排序:

df_inner.sort_values(by=['age'])

4、按照索引列排序:

df_inner.sort_index()

5、如果prince列的值>3000,group列显示high,否则显示low:

df_inner['group'] = np.where(df_inner['price'] > 3000,'high','low')

6、对复合多个条件的数据进行分组标记

df_inner.loc[(df_inner['city'] == 'beijing') & (df_inner['price'] >= 4000), 'sign']=1

7、对category字段的值依次进行分列,并创建数据表,索引值为df_inner的索引列,列名称为category和size

pd.DataFrame((x.split('-') for x in df_inner['category']),index=df_inner.index,columns=['category','size']))

8、将完成分裂后的数据表和原df_inner数据表进行匹配

df_inner=pd.merge(df_inner,split,right_index=True, left_index=True)

五、数据提取
主要用到的三个函数:loc,iloc和ix,loc函数按标签值进行提取,iloc按位置进行提取,ix可以同时按标签和位置进行提取。
1、按索引提取单行的数值

df_inner.loc[3]

2、按索引提取区域行数值

df_inner.iloc[0:5]

3、重设索引

df_inner.reset_index()

4、设置日期为索引

df_inner=df_inner.set_index('date') 

5、提取4日之前的所有数据

df_inner[:'2013-01-04']

6、使用iloc按位置区域提取数据

df_inner.iloc[:3,:2] #冒号前后的数字不再是索引的标签名称,而是数据所在的位置,从0开始,前三行,前两列。

7、适应iloc按位置单独提起数据

df_inner.iloc[[0,2,5],[4,5]] #提取第0、2、5行,4、5列

8、使用ix按索引标签和位置混合提取数据

df_inner.ix[:'2013-01-03',:4] #2013-01-03号之前,前四列数据

9、判断city列的值是否为北京

df_inner['city'].isin(['beijing'])

10、判断city列里是否包含beijing和shanghai,然后将符合条件的数据提取出来

df_inner.loc[df_inner['city'].isin(['beijing','shanghai'])] 

11、提取前三个字符,并生成数据表

pd.DataFrame(category.str[:3])

六、数据筛选
使用与、或、非三个条件配合大于、小于、等于对数据进行筛选,并进行计数和求和。
1、使用“与”进行筛选

df_inner.loc[(df_inner['age'] > 25) & (df_inner['city'] == 'beijing'), ['id','city','age','category','gender']]

2、使用“或”进行筛选

df_inner.loc[(df_inner['age'] > 25) | (df_inner['city'] == 'beijing'), ['id','city','age','category','gender']].sort(['age']) 

3、使用“非”条件进行筛选

df_inner.loc[(df_inner['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id']) 

4、对筛选后的数据按city列进行计数

df_inner.loc[(df_inner['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id']).city.count()

5、使用query函数进行筛选

df_inner.query('city == ["beijing", "shanghai"]')

6、对筛选后的结果按prince进行求和

df_inner.query('city == ["beijing", "shanghai"]').price.sum()

七、数据汇总
主要函数是groupby和pivote_table
1、对所有的列进行计数汇总

df_inner.groupby('city').count()

2、按城市对id字段进行计数

df_inner.groupby('city')['id'].count()

3、对两个字段进行汇总计数

df_inner.groupby(['city','size'])['id'].count()

4、对city字段进行汇总,并分别计算prince的合计和均值

df_inner.groupby('city')['price'].agg([len,np.sum, np.mean]) 

八、数据统计
数据采样,计算标准差,协方差和相关系数
1、简单的数据采样

df_inner.sample(n=3) 

2、手动设置采样权重

weights = [0, 0, 0, 0, 0.5, 0.5]
df_inner.sample(n=2, weights=weights) 

3、采样后不放回

df_inner.sample(n=6, replace=False) 

4、采样后放回

df_inner.sample(n=6, replace=True)

5、 数据表描述性统计

df_inner.describe().round(2).T #round函数设置显示小数位,T表示转置

6、计算列的标准差

df_inner['price'].std()

7、计算两个字段间的协方差

df_inner['price'].cov(df_inner['m-point']) 

8、数据表中所有字段间的协方差

df_inner.cov()

9、两个字段的相关性分析

df_inner['price'].corr(df_inner['m-point']) #相关系数在-1到1之间,接近1为正相关,接近-1为负相关,0为不相关

10、数据表的相关性分析

df_inner.corr()

九、数据输出
分析后的数据可以输出为xlsx格式和csv格式
1、写入Excel

df_inner.to_excel('excel_to_python.xlsx', sheet_name='bluewhale_cc') 

2、写入到CSV

df_inner.to_csv('excel_to_python.csv') 
上一篇下一篇

猜你喜欢

热点阅读