参考资料:
开始
安装 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
-
删除
我们队对Series中的元素执行删除,主要用到.drop函数和.pop函数
drop,
函数原型:def drop(self, labels=None, axis=0, index=None, columns=None,
level=None, inplace=False, errors='raise'):
Series.drop(label) 方法会从给定 Series 中删除给定的 label,删除元素之后返回副本,不会更改原
Series。但drop函数中有一个可变参数,inplace,如果将inplace = True设置的话,就能原地从 Pandas Series 中删除数据然后返回空。
pop 删除源数据,像drop(inplace = True)的情况
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'])
赋值:
以上的取值方法加上赋值运算符就能进行赋值运算。
- 添加
方法一,df.append方法
添加列,df[新列名] = 某某列表,就像字典一样,就添加成功了
添加行,先新建一个df表格,然后在原先的df上使用 .append() 方法,就能将x新建的df添加到原df上了
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])
- 删除
方法一,df.drop方法
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
- 改名
方法一:
DataFrame.rename(mapper=None, index=None, columns=None, axis=None, copy=True, inplace=False, level=None)
>>> 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
- 处理NaN的方法
方法一:
df.isnull()与notnull()
返回是所有数据的true/false矩阵,如果是空的,返回的那个是True,如果是非空的,返回的那个是False。
使用df.isnull().any()则会判断哪些”列”存在缺失值。
.any的方法 是一列中,任何一个为True或者非空非零,就会返回True
notnull与之相反。
方法二:
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
- csv数据分析统计导入
(1)pd.read_csv() 函数将 CSV 文件加载到 Pandas DataFrame 中
(2)pd.head()读取前五个数据,pd.tail()读取后五个数据
(3)pd.isnull() 和pd.any()上面讲过了不再赘述
(4)pd.describe() 方法,可以获取关于 DataFrame 每列的描述性统计信息
(5)pd.corr() 方法获取不同列之间的关联性,关联性值为 1 表明关联性很高,关联性值为 0 告诉我们数据根本不相关。
(6)pd.groupby(),我们常会用group来重新组合进行数据分析
有个网址groupby写的很好,网址, 另外还有groupby 官方api文档
#举例:
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')
网友评论