import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
# header 设置为列表,表示第0、1两行同时作为多层级索引读取
pd.read_excel('datas.xlsx', sheet_name=0, header=[0,1])
隐式构造
最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组
array_ = [["一季度","一季度","一季度","二季度","二季度","二季度"],["A产品","B产品","C产品","A产品","B产品","C产品"]]
#Series创建多层索引
data1 = np.random.randint(0,100,size=6)
DataFrame(Series(data=data1, index=array_)) ==>
0
一季度 A产品 43
B产品 93
C产品 82
二季度 A产品 79
B产品 57
C产品 51
#DataFrame创建多层索引
data = np.random.randint(0,100,size=(3,6))
index = ["小张","小王","小李"]
隐式构造,可以直接使用一个array的表达方式类设置多层级索引
df = DataFrame(data=data, index=index, columns=array_)
df ==>
一季度 二季度
A产品 B产品 C产品 A产品 B产品 C产品
小张 59 40 7 25 91 21
小王 5 70 62 48 42 84
小李 63 4 96 31 85 50
显式构造 使用pd.MultiIndex
#三种方式
1、使用数组
array_ = [["一季度","一季度","一季度","二季度","二季度","二季度"],["A产品","B产品","C产品","A产品","B产品","C产品"]]
columns1 = `pd.MultiIndex.from_arrays`(array_)
DataFrame(data=data, index=index, columns=columns1)
2、使用元组
tuple_ = [["一季度","A产品"],["一季度","B产品"],["一季度","C产品"],["二季度","A产品"],["二季度","B产品"],["二季度","C产品"]]
columns2 = `pd.MultiIndex.from_tuples`(tuple_)
DataFrame(data=data, index=index, columns=columns2)
3、使用全排列product
product_ = [["一季度","二季度"],["A产品","B产品","C产品"]]
columns3 = pd.MultiIndex.from_product(product_)
DataFrame(data=data, index=index, columns=columns3)
除了列索引columns,行索引index也能用同样的方法创建多层索引
data = data.reshape((6,2))
df1 = DataFrame(data=data, index=columns, columns=index) ==>
张三 李四
期中 python 96 42
java 90 97
PHP 26 32
期末 python 50 67
java 35 23
PHP 93 99
对于Series来说,直接中括号[]与使用.loc()完全一样,推荐使用.loc中括号索引和切片。
索引
s[一级索引,二级索引]
s.loc[一级索引,二级索引]
切片
变成单级索引切片
使用隐式索引切片
利用stack、unstack变型之后再切
#索引
s1 ==>
期中 python 26
java 63
PHP 85
期末 python 85
java 80
PHP 45
Name: 张三, dtype: int32
s1["期中","python"]
s1.loc["期中","python"] ==>26
#切片
s1["期中"]["python":"PHP"]
python 26
java 63
PHP 85
Name: 张三, dtype: int32
df ==>
期中 期末
python java PHP python java PHP
张三 99 13 68 64 3 15
李四 58 13 91 75 17 49
#访问
df.iloc[1,4] ==> 17
#切片
df.iloc[:,2:4] ==>
期中 期末
PHP python
张三 68 64
李四 91 75
df1 ==>
张三 李四 王五
期中 python 99 13 15
java 68 64 71
PHP 3 15 34
期末 python 58 13 4
java 91 75 61
PHP 17 49 42
#访问并赋值
df2 = df1.copy()
#变成单机索引(拷贝副本不改变原表的值)
temp = df2.loc["期中"].copy() ==>
张三 李四 王五
python 99 13 15
java 68 64 71
PHP 3 15 34
#赋值
temp.loc["python","张三"] = 0
#将副本的值赋给单级索引
df2.loc["期中"] = temp.values
df1 ==>
张三 李四 王五
期中 python 99 13 15
java 68 64 71
PHP 3 15 34
期末 python 58 13 4
java 91 75 61
PHP 17 49 42
# 访问行
df1.loc["期中","python"]
# 访问元素
# ("期中","python") 可以用来访问元素,但是不能用来切片
df1.loc[("期中","python"),"张三"]
df ==>
期中 期末
python java PHP python java PHP
张三 96 42 90 97 26 32
李四 50 67 35 23 93 99
#元素访问
df.loc["张三",("期中","python")] ==>96
【使用技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里
格式:df.stack(level=-1, dropna=True)
使用
df ==>
期中 期末
python java PHP python java PHP
张三 99 13 68 64 3 15
李四 58 13 91 75 17 49
# level=1 和 level=-1效果一样
df.stack(level=1) ==>
期中 期末
张三 PHP 68 15
java 13 3
python 99 64
李四 PHP 91 49
java 13 17
python 58 75
#level=0 和 level=-2效果一样
df3 = df.stack(level=0)
PHP java python
张三 期中 68 13 99
期末 15 3 64
李四 期中 91 13 58
期末 49 17 75
使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。
#level=0
df3.unstack(level=0) ==>
PHP java python
张三 李四 张三 李四 张三 李四
期中 90 35 42 67 96 50
期末 32 99 26 93 0 23
df ==>
期中 期末
python java PHP python java PHP
张三 96 42 90 0 26 32
李四 50 67 35 23 93 99
#列变行 行变列
df.stack(level=0).unstack(level=0) ==>
PHP java python
张三 李四 张三 李四 张三 李四
期中 68 91 13 13 99 58
期末 15 49 3 17 64 75
df.stack(level=1).unstack(level=0)
期中 期末
张三 李四 张三 李四
PHP 68 91 15 49
java 13 13 3 17
python 99 58 64 75
所谓的聚合操作:平均数,方差,最大值,最小值……
和numpy的区别
DataFrame的聚合,默认是列方向的聚合,可以指定axis来改变。计算的时候假如列表中有NaN时,默认当做0计算
score.sum()
score.sum(axis=1)
numpy默认是对 整个数组聚合,假如求和的数组中有nan时,只能用np.nansum(arr)来处理数组中有nan的情况
np.nansum(arr)
先定义一个生成DataFrame的函数:
# :
def make_DataFrame(index, columns):
all_data = []
for idx in index:
row_data = []
for col in columns:
row_data.append(col + idx)
all_data.append(row_data)
return DataFrame(data=all_data, index=index, columns=columns)
#简易写法
def make_df(index, columns):
return DataFrame({i:[i+str(j) for j in index] for i in columns}, index=index)
使用pd.concat()级联
pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)
#
objs df元组
axis=0 axis控制级联方向,axis=0横向
join='outer' 参数有outer(外联)、inner(内联)
join_axes=None 指定以某个索引进行级联,通常和axis一起使用
ignore_index=False 如果索引没什么实际意义 ignore_index
keys 如果想保留原始标签,可以使用keys参数,来设置多层级索引表格。一般情况下:ignore_index对行索引重新排列,keys对列索引进行分区
df1 = make_DataFrame(index=list("1234"),columns=list("ABCD"))
df2 = make_DataFrame(index=list("2345"), columns=list("ABCD"))
#numpy级联,只考虑数值
np.concatenate((df1.values, df2.values)) ==>
array([['A1', 'B1', 'C1', 'D1'],
['A2', 'B2', 'C2', 'D2'],
['A3', 'B3', 'C3', 'D3'],
['A4', 'B4', 'C4', 'D4'],
['A2', 'B2', 'C2', 'D2'],
['A3', 'B3', 'C3', 'D3'],
['A4', 'B4', 'C4', 'D4'],
['A5', 'B5', 'C5', 'D5']], dtype=object)
#pandas级联
pd.concat((df1, df2),axis=1)
A B C D A B C D
1 A1 B1 C1 D1 NaN NaN NaN NaN
2 A2 B2 C2 D2 A2 B2 C2 D2
3 A3 B3 C3 D3 A3 B3 C3 D3
4 A4 B4 C4 D4 A4 B4 C4 D4
5 NaN NaN NaN NaN A5 B5 C5 D5
#外连接取并集
df5 = make_DataFrame(index=list("123"), columns=list("BCE"))
pd.concat((df1,df5), join="outer", axis=1) ==>
A B C D B C E
1 A1 B1 C1 D1 B1 C1 E1
2 A2 B2 C2 D2 B2 C2 E2
3 A3 B3 C3 D3 B3 C3 E3
4 A4 B4 C4 D4 NaN NaN NaN
# 内联取交集
pd.concat((df1,df5), join="inner", axis=1)
A B C D B C E
1 A1 B1 C1 D1 B1 C1 E1
2 A2 B2 C2 D2 B2 C2 E2
3 A3 B3 C3 D3 B3 C3 E3
#指定B和C列进行级联
pd.concat((df1,df5), join_axes=[pd.Index(["B","C"])])
B C
1 B1 C1
2 B2 C2
3 B3 C3
4 B4 C4
1 B1 C1
2 B2 C2
3 B3 C3
#横向级联,以2和3行为基准
pd.concat((df1, df5), join_axes=[pd.Index(["2","3"])], axis=1)
A B C D B C E
2 A2 B2 C2 D2 B2 C2 E2
3 A3 B3 C3 D3 B3 C3 E3
#左连接
pd.concat((df1, df5), join_axes=[df1.columns])
A B C D
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
1 NaN B1 C1 NaN
2 NaN B2 C2 NaN
3 NaN B3 C3 NaN
#右连接
pd.concat((df1, df5), join_axes=[df5.columns])
B C E
1 B1 C1 NaN
2 B2 C2 NaN
3 B3 C3 NaN
4 B4 C4 NaN
1 B1 C1 E1
2 B2 C2 E2
3 B3 C3 E3
# 如果索引没什么实际意义 ignore_index
pd.concat((df1, df3), ignore_index=True)
0 1 2 3 4 5 6
1 A1 B1 C1 D1 B1 C1 E1
2 A2 B2 C2 D2 B2 C2 E2
3 A3 B3 C3 D3 B3 C3 E3
4 A4 B4 C4 D4 NaN NaN NaN
# 如果想保留原始标签,可以使用keys参数,来设置多层级索引表格
# 一般情况下:ignore_index对行索引重新排列
# keys对列索引进行分区
pd.concat((df1, df3), axis=1, keys=["上学期","下学期"])
上学期 下学期
A B C D B C E
1 A1 B1 C1 D1 B1 C1 E1
2 A2 B2 C2 D2 B2 C2 E2
3 A3 B3 C3 D3 B3 C3 E3
4 A4 B4 C4 D4 NaN NaN NaN
注意:append函数只是沿着axis=0的方向进行级联
# df ==>
python JAVA c
李四 49 45 39
王老五 33 24 54
赵小六 37 57 95
df1 =DataFrame(data=np.random.randint(0,100,size=(1,3)),index=["张三"], columns=df.columns)
#
df.append(df1)
python JAVA c
李四 49 45 39
王老五 33 24 54
赵小六 37 57 95
张三 58 59 6
merge与concat的区别在于,merge需要依据某一共同【列】来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意:每一列元素的顺序不要求一致
merge()的要求:
格式:pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=(’_x’, ‘_y’), copy=True, indicator=False)
#读取外部文件数据
index_col = [0] 设置第一列为作为行索引读取
header = [0] 设置第一行为列索引读取
【注意】版本不同,要确认参数名称是否有变化 比如sheet_name\sheetname
tb1 = pd.read_excel('data/关系表.xlsx',sheetname=1)
tb2 = pd.read_excel('data/关系表.xlsx',sheetname=2)
tb3 = pd.read_excel('data/关系表.xlsx',sheetname=3)
tb4 = pd.read_excel('data/关系表.xlsx',sheetname=4)
#各个标的数据
td1 ==>
手机型号 参考价格
0 windowsPhone 2500
1 iPhone 7500
2 Android 4000
td2 ==>
手机型号 重量
0 windowsPhone 0.50
1 iPhone 0.40
2 Android 0.45
3 other 0.60
tb3 ==>
经销商 发货地区 手机型号
0 dancer beijing iPhone
1 lucy beijing Android
2 tom guangzhou iPhone
3 petter shenzhen windowsPhone
4 mery guangzhou Android
tb4 ==>
发货地区 手机型号 价格
0 beijing iPhone 7000
1 beijing windowsPhone 2300
2 beijing Android 3600
3 guangzhou iPhone 7600
4 guangzhou windowsPhone 2800
5 guangzhou Android 4200
6 shenzhen iPhone 7400
7 shenzhen windowsPhone 2750
8 shenzhen Android 3900
#默认会把相同的列标签的列作为合并参考,进行合并
#如果存在多个列都可以合并,则同时以多列作为合并参考
pd.merge(tb1, tb2) ==>
手机型号 参考价格 重量
0 windowsPhone 2500 0.50
1 iPhone 7500 0.40
2 Android 4000 0.45
#how inner 取交集
# outer 取并集 如果存在不同项目,以NaN填充
# left 以left参数指定的表为准
# right 以right参数指定的表为准
pd.merge(tb1, tb2, how="right") ==>
手机型号 参考价格 重量
0 windowsPhone 2500.0 0.50
1 iPhone 7500.0 0.40
2 Android 4000.0 0.45
3 other NaN 0.60
#使用on=显式指定哪一列为key,当有多个key相同时使用
#suffixes 当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名
可以使用suffixes=自己指定后缀
pd.merge(tb3, tb4, on="手机型号", suffixes=["_上半年","_下半年"]) ==>
经销商 发货地区_上半年 手机型号 发货地区_下半年 价格
0 dancer beijing iPhone beijing 7000
1 dancer beijing iPhone guangzhou 7600
#这里把表5的数据的列索引改为‘型号’再和表一进行合并
tb5 = tb2.copy()
tb5.columns = ["型号","重量"]
# left_on right_on 用于当合并的列名称不一样时,可以分别指定参考的列的列标签
pd.merge(tb1, tb5, left_on="手机型号", right_on="型号").drop(labels=["型号"],axis=1) ==>
手机型号 参考价格 重量
0 windowsPhone 2500 0.50
1 iPhone 7500 0.40
2 Android 4000 0.45
#set_index 把某一列设置为DataFrame的行索引
tb6 = tb5.copy()
tb6 = tb6.set_index("型号") ==>
重量
型号
windowsPhone 0.50
iPhone 0.40
Android 0.45
other 0.60
#right_index 指定右表的行索引为合并列的标签
pd.merge(tb1, tb6, left_on="手机型号", right_index=True)
pd.merge(tb6, tb1, left_index=True, right_on="手机型号")
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
#表一
abb = pd.read_csv('data/state-abbrevs.csv')
abb.head() ===>
state abbreviation
0 Alabama AL
1 Alaska AK
2 Arizona AZ
3 Arkansas AR
4 California CA
#表二
area = pd.read_csv('data/state-areas.csv')
area.head() ==>
state area (sq. mi)
0 Alabama 52423
1 Alaska 656425
2 Arizona 114006
3 Arkansas 53182
4 California 163707
#表三
pop = pd.read_csv('data/state-population.csv')
pop.head()
state/region ages year population
0 AL under18 2012 1117489.0
1 AL total 2012 4817528.0
2 AL under18 2010 1130966.0
3 AL total 2010 4785570.0
4 AL under18 2011 1125763.0
pop_abb = pd.merge(pop, abb, how="outer", left_on="state/region", right_on="abbreviation")
pop_abb.head() 表一和表三合并 ==>
state/region ages year population state abbreviation
0 AL under18 2012 1117489.0 Alabama AL
1 AL total 2012 4817528.0 Alabama AL
2 AL under18 2010 1130966.0 Alabama AL
3 AL total 2010 4785570.0 Alabama AL
4 AL under18 2011 1125763.0 Alabama AL
## 对比pop_abb表中,相同的两列的信息是否一致
pop_abb["state/region"].unique()
pop_abb["abbreviation"].unique()
# 2. 查看不同的信息出现的次数
pop_abb["state/region"].value_counts()
pop_abb["abbreviation"].value_counts()
# 可以使用info函数,查看一个DataFrame的整体信息
pop_abb.info()
#经过比较决定去除abbreviation的那一列(axis=1)
# 删除一列,改变输入的内存,注意不要多次运行,只运行一次
pop_abb.drop(labels="abbreviation",axis=1, inplace=True)
#获取行bool_list 用来过滤缺失值
bool_list = pop_abb.isnull().any(axis=1)
empty_df = pop_abb.loc[bool_list] ==>
state/region ages year population state abbreviation
2448 PR under18 1990 NaN NaN NaN
2449 PR total 1990 NaN NaN NaN
2450 PR total 1991 NaN NaN NaN
2451 PR under18 1991 NaN NaN NaN
2452 PR total 1993 NaN NaN NaN
#找到有哪些state/region使得state的值为NaN,使用unique()查看非重复值
# 如果返回的是True,说明该列都是空置
empty_df["state"].isnull().all()
empty_df["state/region"].unique()
PR_COND = pop_abb["state/region"] == "PR"
USA_COND = pop_abb["state/region"] == "USA"
#给PR州赋值
pop_abb.loc[PR_COND,"state"] = "Puerto Rico"
pop_abb.loc[USA_COND,"state"] = "USA"
#检测列方向是否还有空值
pop_abb.isnull().any() ==>
state/region False
ages False
year False
population True #为空的行删除
state False
abbreviation True
dtype: bool
#检测人口空值
pop_abb.loc[pop_abb.isnull().any(axis=1)]
#检测表2和pop_abb表的不同
area["state"].size ==>52
pop_abb["state/region"].unique().size ==>53
#左联两个表
total = pd.merge(pop_abb, area, how="left")
# 先查看列是否存在缺失
total.isnull().any()
# 查找包含空值的行
total.loc[total.isnull().any(axis=1)]
# 获取所有包含空值的行索引
drop_index = total.loc[total.isnull().any(axis=1)].index
# 删除包含空值的行
total.drop(labels=drop_index, axis=0, inplace=True)
total.isnull().any() #此时总表里没有空值
#常规做法
year_conditon = total["year"] == 2010
total_2010 = total.loc[year_conditon]
total_2010_result = total_2010.loc[total_2010["ages"] == "total"]
#把州名设置为行索引
total_2010_result.set_index("state",inplace=True)
#使用query语句简化版,query直接接收一个字符串表达式 多个条件使用&连接
rest1 = total_2010.query('year == 2010 & ages == "total"').set_index("state")
#计算人口密度
ret1 = rest1["population"]/rest1["area (sq. mi)"]
#绘直方图
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(24,8))
ret1.plot(kind="bar")
#排序,并找出人口密度最高的五个州sort_values()
#ascending 默认为升序,改为降序切片取前五个
ret3 = ret1.sort_values(ascending=False)[:5]
ret3.plot(kind="bar")
删除数据三个方式
使用duplicated()函数查看重复的行
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
condition = df.duplicated(keep="last") ==>
0 True
1 False
2 True
3 False
4 False
5 True
6 False
7 False
dtype: bool
#利用condition过滤出行索引
df.loc[condition].index ==>
Int64Index([0, 2, 5], dtype='int64')
#删除相同的数据
df.drop(labels=df.loc[condition].index)
# 如果需要对级联后的表进行去重, 最好把索引进行重排操作
df3 = pd.concat((df,df), ignore_index=True)
df3.drop_duplicates() ==>
name 语文 数学 英语
0 王伟 67 76 65
1 张小凡 87 54 87
2 陆雪琪 56 98 67
3 黎明 56 67 65
4 碧瑶 54 56 90
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定 ,包含三种操作:
df.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad', axis=None)
method:对指定的值使用相邻的值填充
limit:设定填充次数
df ==>
A B C D E
0 lucy 65 43.0 6.836381 22.0
1 mery 57 NaN NaN 85.0
2 tom 66 80.0 2.858967 11.0
3 jack 42 66.0 8.044660 NaN
4 rose 79 17.0 0.047589 31.0
# 单值替换
df.replace(to_replace="lucy", value="魏淑芬")
# 列表替换
df.replace(to_replace=["lucy","mery",np.nan], value=["魏淑芬","王可",0])
# 字典替换
# 1. 要替换的值,字典里没有 , 默认保留原始值
# 2. 字典里存在的值,在要替换的 值里没有, 所以,根据以上的特征,我们可以直接维护一个字典,对所有的表进行替换
df.replace(to_replace={
"lucy":"魏淑芬",
"mery":"王小可",
"noname":"不知道"
})
s.map(arg, na_action=None)
map函数并不是DataFrame的函数,而是Series的函数, 所以map函数主要用于某一列数据的映射处理
注意
map函数可以接收如下三种值:
df ===>
name 语文 数学 英语
0 王伟 67 76 65
1 张小凡 87 54 87
2 陆雪琪 56 98 67
3 黎明 56 67 65
4 碧瑶 54 56 90
#接收字典
map_dic = {
"黎明":"Tom",
"碧瑶":"Green",
"陆雪琪":"Rose",
"王伟":"Jery",
"张小凡":"Lucy",
"张学友":"Friend"
}
# 新增一列
df["english_name"] = df["name"].map(map_dic)
# 修改一列
df["name"] = df["name"].map(map_dic)
#1. 字典里面的键值对如果多于要映射的列的数据,可以维护一个大字典,对多列数据进行映射处理
df["name"].map(map_dic)
# 2. 字典里面的键值对少于要映射的列的数据, 没有对应映射数据将会返回一个NaN,可以使用函数,如果字典里有对应的映射值就返回映射至,否则返回原始值
map_dic = {
"黎明":"Tom",
"碧瑶":"Green"
}
df["name"].map(map_dic)
#接收函数
def function1(x):
return map_dic.get(x,x)
df["name"].map(function1)
def map_score(x):
if x >=90:
return "A"
elif x>=80:
return "B"
elif x >= 70:
return "C"
elif x >= 60:
return "D"
else:
return "E"
df["语文"] = df["语文"].map(map_score)
# lambda 函数
df["英语"].map(lambda x:x-10)
s.transform(func, *args, **kwargs)
df.rename(index=None, columns=None, **kwargs)
仍然是新建一个字典,使用rename()函数替换行索引
#原数据
df ==>
name 语文 数学 英语 english_name
0 王伟 67 76 65 Jery
1 张小凡 87 54 87 Lucy
2 陆雪琪 56 98 67 Rose
3 黎明 56 67 65 Tom
4 碧瑶 54 56 90 Green
# 改变列索引
df.rename(columns={
"name":"姓名"
})
#改变行索引
df.rename(index={
0:"first"
})
#mapper用于指定替换行和列索引的字典,axis用于指定替换的是行索引还是列索引
df.rename(mapper={
0:"first",
"name":"姓名"
},axis=1)
# level 用于指定多层级索引的替换层级
df1 = pd.concat((df, df), axis=1, keys=["上学期","下学期"])
df1.rename(mapper={
"上学期":"第一学期",
"name":"姓名"
}, axis=1, level=1)
异常值界定不同业务有不同的标准
假设某一个数据的绝对值 > 3*该列的标准差 就被认定为异常数据
df = DataFrame(data = np.random.randn(10000,3), columns=list("ABC"))
# describe() 函数查看数据集的基本数学指标
df.describe() ==>
A B C
count 10000.000000 10000.000000 10000.000000
mean -0.002205 -0.002600 -0.000615
std 1.010709 1.000173 1.013830
min -4.053966 -4.535207 -3.455074
25% -0.684367 -0.690652 -0.688193
50% -0.009133 0.000911 0.014746
75% 0.675410 0.675980 0.695004
max 3.808636 3.865321 4.074260
#最大值
df["A"].max()
#标准差 #接近1,使用std()函数可以求得DataFrame对象每一列的标准差
df["A"].std()
# 确定异常值的检测条件
condition = np.abs(df) > 3*df.std() ==>
A B C
0 False False False
1 False False False
2 False False False
''''''
# 获取满足条件的行
bool_list = condition.any(axis=1)
# 获取满足条件的行的索引
drop_index = df[bool_list].index
# 根据满足条件的行的索引,删除行
df.drop(labels=drop_index)
可以借助np.random.permutation()函数随机排序
df = DataFrame(data=np.random.randint(0,10,size=(5,5)), columns=list("ABCDE"))
A B C D E
0 2 2 6 4 1
1 7 1 6 7 7
2 2 5 4 1 7
3 3 0 1 2 9
4 9 0 5 7 5
#列方向取
df.take([0,1,0,1],axis=1) ==>
A B A B
0 2 2 2 2
1 7 1 7 1
2 2 5 2 5
3 3 0 3 0
4 9 0 9 0
# 使用permutation函数随机生成数组
np.random.permutation(5) 生成随机排序数组==>
array([0, 1, 2, 4, 3])
df.take(np.random.permutation(5),axis=1)
##
df.take(indices,axis)
np.random.permutation() # 随机排序
np.random.randint() # 随机抽样
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
数据分类处理的核心:
groupby()函数
groups属性查看分组情况
总结:数据类型是离散的可以分组,连续的没有意义
获取weight的总和
把总和跟df进行merge合并
使用列表进行多列分组,得到的结果是多层级索引
df = pd.read_excel('cai.xlsx')
item color price weight
0 萝卜 红 0.5 50
1 白菜 白 0.3 30
2 白菜 青 1.0 16
3 萝卜 青 1.0 32
4 辣椒 青 2.0 36
5 白菜 红 3.0 18
6 冬瓜 青 1.5 29
7 辣椒 红 4.0 18
8 辣椒 黄 0.5 19
9 冬瓜 白 2.0 23
# 分组 根据item列进行分组
ret = df.groupby("item") ==>
<pandas.core.groupby.DataFrameGroupBy object at 0x000000000A6FA390>
# 查看分组情况
ret.groups ==>
{'冬瓜': Int64Index([6, 9], dtype='int64'),
'白菜': Int64Index([1, 2, 5], dtype='int64'),
'萝卜': Int64Index([0, 3], dtype='int64'),
'辣椒': Int64Index([4, 7, 8], dtype='int64')}
# 查看不同菜品的总重量
# 可以直接对分组对象做聚合操作
ret.sum()["weight"]
item
冬瓜 52
白菜 64
萝卜 82
辣椒 73
Name: weight, dtype: int64
#每种蔬菜均价
ret.mean()["price"]
item
冬瓜 1.750000
白菜 1.433333
萝卜 0.750000
辣椒 2.166667
Name: price, dtype: float64
# 聚合之前,先确认要聚合的列是否能运算
df.dtypes
# 同时查看价格的平均值和重量的总和
ret.agg({"price":"mean", "weight":"sum"})
# 多层级索引分组,可以用于查看两个列之间的对应关系
df.groupby(["color","item"]).sum()["weight"]
df.groupby(["item","color"]).sum()["weight"]
item color
冬瓜 白 23
青 29
白菜 白 30
红 18
青 16
萝卜 红 50
青 32
辣椒 红 18
青 36
黄 19
Name: weight, dtype: int64
使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
df.groupby('item').sum()["price"] ==>
item
冬瓜 3.5
白菜 4.3
萝卜 1.5
辣椒 6.5
Name: price, dtype: float64
df.groupby('item').apply(sum)["price"] ==>
item
冬瓜 3.5
白菜 4.3
萝卜 1.5
辣椒 6.5
Name: price, dtype: float64
#使用函数
def function(items):
result = 0
for item in items:
result += item
return result
r1 = df.groupby("item")["price"].apply(function)
item
冬瓜 3.5
白菜 4.3
萝卜 1.5
辣椒 6.5
Name: price, dtype: float64
#
r2.name = "price_sum"
pd.concat((df, r2),axis=1) ==>
item color price weight price_sum
0 萝卜 红 0.5 50 1.5
1 白菜 白 0.3 30 4.3
2 白菜 青 1.0 16 4.3
3 萝卜 青 1.0 32 1.5
4 辣椒 青 2.0 36 6.5
5 白菜 红 3.0 18 4.3
6 冬瓜 青 1.5 29 3.5
7 辣椒 红 4.0 18 6.5
8 辣椒 黄 0.5 19 6.5
9 冬瓜 白 2.0 23 3.5
注意
transform 会自动匹配列索引返回值,不去重
apply 会根据分组情况返回值,去重
DataFrame.corr(method='pearson', min_periods=1)
参数说明:
method:可选值为{‘pearson’, ‘kendall’, ‘spearman’}
pearson:Pearson相关系数来衡量两个数据集合是否在一条线上面,即针对线性数据的相关系数计算,针对非线性 数据便会有误差。
kendall:用于反映分类变量相关性的指标,即针对无序序列的相关系数,非正太分布的数据
spearman:非线性的,非正太分析的数据的相关系数
min_periods:样本最少的数据量
返回值:各类型之间的相关系数DataFrame表格。
为区分不同参数之间的区别,我们实验如下:
from pandas import DataFrame
import pandas as pd
x=[a for a in range(100)]
#构造一元二次方程,非线性关系
def y_x(x):
return 2*x**2+4
y=[y_x(i) for i in x]
data=DataFrame({'x':x,'y':y})
#查看下data的数据结构
data.head()
Out[34]:
x y
0 0 4
1 1 6
2 2 12
3 3 22
4 4 36
data.corr()
Out[35]:
x y
x 1.000000 0.967736
y 0.967736 1.000000
data.corr(method='spearman')
Out[36]:
x y
x 1.0 1.0
y 1.0 1.0
data.corr(method='kendall')
Out[37]:
x y
x 1.0 1.0
y 1.0 1.0
因为y经由函数构造出来,x和y的相关系数为1,但从实验结构可知pearson系数,针对非线性数据有一定的误差。
接下来是房价分析的例子:
corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False) ==>
out:
median_house_value 1.000000
median_income 0.687160
total_rooms 0.135097
housing_median_age 0.114110
households 0.064506
total_bedrooms 0.047689
population -0.026920
longitude -0.047432
latitude -0.142724
Name: median_house_value, dtype: float64
可以看出,房价与收入有比较强的相关性,而与纬度的相关性很低。
pandas.plotting.scatter_matrix(frame, alpha=0.5, figsize=None, ax=None, grid=False, diagonal=‘hist’, marker=’.’, density_kwds=None, hist_kwds=None, range_padding=0.05, **kwds)
画任意两列数值属性的散点图,最后画一个散点图的矩阵,对角线为分布直方图。
df = DataFrame(np.random.randn(1000, 4), columns=['A','B','C','D'])
scatter_matrix(df, alpha=0.2)
继续分析房价的例子,通过计算相关系数,只看几个与房价相关性较大的数据
from pandas.tools.plotting import scatter_matrix
attributes = ["median_house_value", "median_income", "total_rooms",
"housing_median_age"]
scatter_matrix(housing[attributes], figsize=(12, 8))