pandas以前笔记

# -*- coding: utf-8 -*-
"""
Created on Sat Jul 21 20:06:20 2018

@author: heimi
"""
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import numpy as np
#导入自定义模块
import sys
from pandas import Series,DataFrame
from numpy import nan as NA
from os import path
# sys.path.append( path.dirname(path.dirname(path.abspath(__file__))))
# import mytools.midtools as midtools
# from matplotlib.font_manager import FontProperties
#显示中文
# font=FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=12)

path=r'D:/code12temp/自己笔记/'
pd.set_option('display.width',None)

data=DataFrame(np.arange(16).reshape(4,4),index=list("ABCD"),columns=list("wxyz"))
print(data)

#可以直接取列索引,行索引确不行
aa=data["w"]
bb=data[1:2]   #行数值切片
cc=data[1:2,1:2]   #不能同时切片,也就是中间不能有逗号



# Series数据的连接
s1 = Series([0,1],index=["a","b"])
s2 = Series([2,3,4],index=["c","d","e"])
s3 = Series([5,6],index=["f","g"])
result = pd.concat([s1,s2,s3])
result

result = pd.concat([s1,s2,s3],keys=["one","two","three"])
result
#直接在外面再追加一层索引

#合并重叠数据
a = Series([NA,2.5,NA,3.5,4.5,NA],index=list("fedcba"))
b = Series(np.arange(len(a)),dtype=np.float64,index=list("fedcba"))
pd.concat([a,b])

#用其中一个Series中的数据给另一个Series中的数据作为补丁
resultB = b[:-2]
resultB
resultA = a[2:]
resultA
resultB.combine_first(resultA)   #二者索引相同的时候  用ResultB的索引优先
# 而且B的元素为NAN的,通过A中有点来填充,B 中没有的,A中有的,直接填上
# 反正就是A的元素只会增加,不会减少

#创建层次化索引  两层索引
data = Series(np.random.randn(10),index= [list("aaabbbccdd"),[1,2,3,1,2,3,1,2,2,3]])
data

# 将行索引(index)转换到列索引上(columns)   没行列
result = data.unstack()
result
result.stack()

# DataFrame 中的行索引和列索引的重塑和转换
data = DataFrame(np.arange(6).reshape(2,3),
                index=pd.Index(["上海","北京"],name="省份"),
                columns=pd.Index([2011,2012,2013],name="年份"))
data
# 将DataFrame的列索引转化到行索引   烈士
result = data.stack()

#将DataFrame的行索引转化为列索引
#unstack()默认转换的最内层的层次化索引
result.unstack()
#第一种方法,转换的时候,指定层次化索引的名称
result=result.unstack("省份")    #相当于交换了行列
result.stack()

#第二种方法,转换的时候,指定层次化的索引   0是result的第一列,1是后面一层
data=result.unstack(1)
data.unstack(1)


#在对DataFrame进行unstack操作时,作为旋转轴的级别将会成为结果中的最低级别
data = DataFrame(np.arange(6).reshape(2,3),
                 index=pd.Index(["Ohio","Colorado"],name="state"),
                 columns=pd.Index(["one","two","three"],name="nu mbers"))
data
result = data.stack()

df = DataFrame({"left":result,        #直接以series 为对象 并带来了行索引
               "right":result+5},
              columns=pd.Index(["left","right"],name="side"))
df

result = df.unstack("state")   #放到原来索引的下一层

s1=Series([0,1,2,3],index=list("abcd"))
s2 = Series([4,5,6],index=list("cde"))
#将s1和s2拼接成一个具有层次化索引的Series
result = pd.concat([s1,s2],keys=["one","two"])
result
#将结果中的行索引变成列索引   #多层索引序号以零开头
tempResult = result.unstack(1)
tempResult

#全部还原,空值用NaN填充
tempResult.stack(dropna=False)

# 3、pandas高级应用–数据转化、清除重复数据
data = DataFrame({"k1":["one"]*3+["two"]*4,
                "k2":[1,1,2,3,3,4,4]})
#第一种方法,去重
#检测DataFrame中的每行数据是否为重复数据行
mask = data.duplicated()  #当前行的记录和上一行记录进行比较
mask

#通过花式索引去除重复的数据
data[~mask]      #保留为false的

#第二种方法:去重
#通过DataFrame内置的drop_duplicates()方法去除重复的数据行.
#去除

data.drop_duplicates()
data["v1"] = range(7)

# 只以k1这一列为标准去重
data.drop_duplicates(["k1"])

#通过制定keep参数制定需要保留特定的重复数据
#keep="first"  保留重复数据第一次出现的行索引
#keep="last"   保留重复数据最后一次的行索引
#keep=False  只要有重复数据,就全部丢掉

data=DataFrame({'food':['bacon','pulled pork','bacon','Pastrami',
                       'corned beef','Bacon','pastrami','honey ham','nova lox'],
               'ounces':[4,3,12,6,7.5,8,3,5,6]})

meat_to_animal={
    'bacon':'pig',
    'pulled pork':'pig',
    'pastrami':'cow',
    'corned beef':'cow',
    'honey ham':'pig',
    'nova lox':'salmon'}
data["animal"]=data["food"].map(str.lower).map(meat_to_animal)
data["animal"] = data['food'].map(lambda x: meat_to_animal[x.lower()])
#这里的x.lower相当key了

# 4、pandas高级应用–数据替换
series = Series([1,-999,2,-999,-1000,3])
#单个数据替换
series.replace(-999,NA)
#多个数据替换
series.replace([-999,-1000],NA)

#replace方法传入字典,针对不同的值,进行不同的替换
#第一种方法
series.replace({-999:NA,-1000:0})

#第二种方法
series.replace([-999,-1000],[NA,0])

# 5、pandas高级应用–数据拆分
from matplotlib import pyplot as plt

age = [20,22,25,27,21,23,37,31,61,45,41,32]
#将所有年龄进行分组
bins = [18,25,35,60,100]    #前开后闭
#使用pandas中的cut对年龄数据进行分组
cats = pd.cut(age,bins)

#调用pd.value_counts方法统计每个区间段的人数
pd.value_counts(cats)   #直接统计

#区间属于那一行索引   按大小排序的
cats.codes

#为分类出每一组年龄加上标签
group_names = ["Youth","YouthAdult","MiddleAged","senior"]

#用group_name中的值,把区间替换
personType = pd.cut(age,bins,labels=group_names)   #为什么这里不对

plt.hist(personType)
plt.show()

# 06、pandas高级应用–数据分割

data = np.random.randn(1000)   # 服从正太分布
result = pd.qcut(data,4)       # cut将data数据均分为4组
result

# 统计落在每个区间的元素个数
pd.value_counts(result)

# cut函数分割一组数据  cut计算:找出data中的最大值最小值,之差除以4,得出区间值,然后以这个区间值分四份
data = np.random.randn(20)

# 用cut函数将一组数据分割成n份  precision:保留小数点的有效位数
result = pd.cut(data,4,precision=2)
pd.value_counts(result)

data = np.random.randn(1000)
# 根据分位数差的百分比分割
result=pd.qcut(data,[0,0.1,0.5,0.9,1.0])
pd.value_counts(result)

# 如果分为数的差值的和小于1的情况    分割的结果,安装分位数差之和计算
result = pd.qcut(data,[0,0.1,0.3,0.75])
pd.value_counts(result)

# series.str.contains
# http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html

# 07、pandas高级应用–数据的过滤和筛选
#
data = np.random.randn(1000,4)
df = DataFrame(data)
# np.random.seed(num)  #num是生成随机数的种子
# np.random.randn()    ##默认生成随机数的种子数是当前时间的时间戳
#定义一个种子数
np.random.seed(33)
np.random.rand()


np.random.seed(12345)
data = DataFrame(np.random.randn(1000,4))
data
# 简单的数据统计信息
data.describe()

# 获取数据的第四列
col = data[3]
# 筛选出绝对值大于3的数   #对series 直接饮用 np的数学函数,用中括号来放置条件
col[np.abs(col)>3]

# 查找出数据集中有任意某一列的值出现大于3的行数据
data[(np.abs(data)>3).any(1)]       #对所有列进行处理

# 将所有绝对值大于3的正数设置为3,绝对值大于3的负数设置为-3
# 获取数据的符号
data[np.abs(data)>3] = np.sign(data)*3  #取符号
data.describe()
# 08、pandas高级应用–读写文件数据
import sys

# pandas读取csv文件
data = pd.read_csv('data/ex1.csv')
data
# 读取的csv文件没有标题,默认分配表头索引
pd.read_csv('data/ex2.csv',header=None)
# 自定义添加标题
pd.read_csv('data/ex2.csv',names=['a','b','c','e','name'])
# 指定行索引
pd.read_csv('data/ex2.csv',names=['a','b','c','e','name'],index_col='name')   #不是很懂

# 将读取的数据进行层次化索引
pd.read_csv('data/csv_mindex.csv',index_col=['key1','key2'])

# 通过skiprows参数指定需要跳过的行索引
pd.read_csv('data/ex4.csv',skiprows=[0,2,3])

# 加载存在NaN值缺值数据,把na_values对应的值替换为NaN
pd.read_csv('data/ex5.csv',na_values=3)

# 把数据集中的NAN值替换
data.to_csv(sys.stdout,na_rep=['NULL'])

# 只写入数据,不写入行和列的索引
data.to_csv(sys.stdout,index=False,header=False)
data.to_csv('data/aa.csv',index=False,header=False)

# 通过columns来指定写入文件中的列
data.to_csv(sys.stdout,index=False,columns=['a','c','message'])

# 09、pandas高级应用–数据的聚合及分组计算

df = DataFrame({"key":['a','a','b','b','a'],
                 "key2":['one','two','one','two','one'],
                 "data1":np.random.randn(5),
                 "data2":np.random.randn(5)})
df
# 选取data1数据列按照key1进行分组
groupd = df["data1"].groupby(df['key'])  #除了可以按列分组,也可以按行分组
# 调用已经分组好的数据中一些方法,即可得出相应的统计结果
# 获取分组中每一组数据的平均值
groupd.mean()

# 根据key和key2两个列数据进行分组
grouped = df['data1'].groupby([df['key'],df['key2']])
# 求平均
grouped.mean()

# 获取分组后每一组中相应元素出现的次数
df.index
df.groupby([df['key'],df['key2']]).size()    #或 df.groupby(['key','key2']).size()   #按行索引分组

# for  in  循环输出分组的结果
for name,group in df.groupby("key"):
    print(name)
    print(group)

# 将groupby 分类结果转化成字典
pices = dict(list(df.groupby('key')))   #list的时候以逗号分隔key和values,dict 以分号代替逗号
pices['b']

# 按照列的数据类型分组
group = df.groupby(df.dtypes,axis=1)
dict(list(group))
group.size()

# 选择分类数据中的一个或一组
# 方法一:  生成的数据类型是DataFrame
df.groupby(['key','key2'])[['data2']].mean()

# 方法二:  生成的类型是series
df['data2'].groupby([df['key'],df['key2']]).mean()   #series 的groupby 和 dataframe 的groupby 是不一样的

# 方法三:
df.groupby(['key','key2'])['data2'].mean()

# 通过字典或series进行分组
people = DataFrame(np.random.randn(5,5),columns=list('abcde'),index=['Joe','Stenve','Wes','Jim','Travis'])
people
# 创建一个将列名进行映射的字典
mapping = {'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
by_columns = people.groupby(mapping,axis=1)   #相当于对列进行分组
gp=dict(list(by_columns))   #分组之后结果展示
gp['blue']
by_columns.sum()   #横向相加

# 将mapping转化成Series
seriesMap = Series(mapping)

people.groupby(seriesMap,axis=1).count()   #即是不是这个dataframe的列也是可以作为分组的   #对列的数目进行统计  对每个行索引来说

# 分组后常用的计算方法
dict_obj = {'key1' : ['a', 'b', 'a', 'b', 'a', 'b', 'a', 'a'],
            'key2' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
            'data1': np.random.randint(1,10, 8),
            'data2': np.random.randint(1,10, 8)}
df = DataFrame(dict_obj)

# 按照key1进行分组求和
df.groupby('key1').sum()
df[['data1']].groupby(df['key1']).sum()
# 求最大值
df.groupby('key1').max()

df.groupby('key1').describe()

# 第一种方法
# 定义一个函数,求获得DataFrame中某一列数据的最大值和最小值之差
def peak_range(df):
    print(type(df))
    return df.max()-df.min()

df.groupby('key1').agg(peak_range)    #分组之后对每列进行函数处理
# 用匿名函数的方式
#  第二种方法
df.groupby('key1').agg(lambda df: df.max()-df.min())


# 使用agg对分组后的数据调用多个聚合函数
df.groupby('key1').agg(['mean','sum','count','min','std',peak_range])     # 带引号的参数是内置聚合函数

df.groupby('key1').agg(['mean','sum','count','min','std',('ptp',peak_range)])  #peak_range 给peak_range起一个别名,叫ptp  #起别名

# 使用字典实现数据集的每列作用不同的聚合函数
dict_mapping = {'data1':'mean','data2':'sum'}
df.groupby('key1').agg(dict_mapping)      #agg 传入函数   对每列进行不同的操作

# 以"没有索引形式"返回聚合函数的计算结果
df = pd.DataFrame(data={'books':['bk1','bk1','bk1','bk2','bk2','bk3'], 'price': [12,12,12,15,15,17]})
# 将分组之后的books列作为索引
df.groupby("books",as_index=True).sum()   #默认对剩下的price  进行处理

# 不让分组之后的books列作为索引
df.groupby("books",as_index=False).sum()

tips=pd.read_csv(path+'/input/pandasData/tips.csv',encoding='gbk')
# 10、pandas高级应用–分组计算apply
# 为tips数据集添加新的一列,作为客户给的小费占消费总额的百分比
tips['tip_pct'] = tips['tip']/tips['total_bill']

# 定义函数,筛选出小费占比最大的前五条数据
def top(df,n=5,columns='tip_pct'):
    return df.sort_values(by=columns)[-n:]
top(tips,n=6)

#对数据集按抽烟进行分组
group = tips.groupby('smoker')

group

# 使用apply方法分别求出抽烟和不抽烟的客户中的消费占比排在前五客户
group.apply(top)   #直接对分组结果进行应用函数  相当于对两类都进行了处理

# 显示抽烟和不抽烟客户的数量
group.size()
group.count()

# 为apply中使用的函数传参
tips.groupby(['smoker','day'],group_keys=False).apply(top,columns='total_bill',n=2)   #前面是函数,后面是参数
#不显示key
frame = pd.DataFrame({'data1': np.random.randn(1000),
                    'data2': np.random.randn(1000)})

result = pd.cut(frame.data1,4)   #每个值对应一个区间
pd.value_counts(result)

# 定义一个函数,求data1数据列各项参数计算
def get_stats(group):
    return { 'min': group.min(), 'max': group.max(),
            'count':group.count(), 'mean': group.mean() }
grouped = frame.data2.groupby(result)

dict(list(grouped))

grouped.apply(get_stats).unstack()

# 加权平均和相关系数
df = pd.DataFrame({'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b','b'],
                   'data': np.random.randn(8), 'weights': np.random.rand(8)})
grouped = df.groupby('category')
grouped.size()

# Python数据处理进阶——pandas
# https://www.cnblogs.com/llhy1178/p/6762459.html

df = DataFrame(np.random.randn(4,3), columns= list("bde"),
               index= ["Utah", "Ohio", "Texas", "Oregon"])

# print np.abs(df)
# 将函数应用到各列或行所形成的一维数组上。
f = lambda x : x.max() - x.min()
# 每一列的最大值减最小值
print (df.apply(f, axis=0))
# 每一行的最大值减最小值
print (df.apply(f, axis=1))
# 返回值由多个值组成的Series

# 返回值由多个值组成的Series
def f(x):
    return Series([x.min(), x.max()], index=["min","max"])  #对每列进行处理
print (df.apply(f))   #默认是对列进行操作
# 保留两位小数点
format = lambda x : "%.2f" % x
print (df.applymap(format))    #apply对series和对整个dataframe,applymap 对整个dataframe,map对series
print (df["e"].map(format))
# 总的来说就是apply()是一种让函数作用于列或者行操作,applymap()是一种让函数作用于DataFrame每一个元素的操作,而map是一种让函数作用于Series每一个元素的操作



# 排序和排名
obj = Series(np.arange(4.), index=["b","a","d","c"])
# print obj.sort_index()
frame = DataFrame(np.arange(8).reshape((2,4)),index=["three","one"],
                  columns=["d",'a','b','c'])
# 按照索引的行进行排序
print (frame.sort_index(axis=1))
# 按照索引的列进行排序
# print frame.sort_index(axis=0)
# 按照值的列进行排序(必须传入一个列的索引且只能排列一组)
frame.sort_values('b', axis=0, ascending=False)
# 按照值的行进行排序(必须传入一个行的索引且只能排列一组)
frame.sort_values("one", axis=1, ascending=False)
# 根据多个列进行排序
frame.sort_index(by=["a","b"])


# 排名
obj1 = Series([7,-5,7,4,2,0,4])
obj1.rank()

# 加减乘除   add代表加,sub代表减, div代表除法, mul代表乘法
df1 = DataFrame(np.arange(12).reshape((3,4)), columns=list("abcd"))
df2 = DataFrame(np.arange(20).reshape((4,5)), columns=list("abcde"))

df1 + df2   #找不到匹配的位置直接为空
# 将缺失值用0代替
df1.add(df2, fill_value=0)  #找不到匹配的位置用单独一方的值替代
# 再进行重新索引时,也可以指定一个填充值
df1.reindex(columns=df2.columns, fill_value=0)


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 = DataFrame(data)
# frame
# 矩阵的横坐标
# frame.columns
# 矩阵的纵坐标
# print frame.index
# 获取列通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series:
# print frame["state"]
# print frame.year
# 获取行也通过类似字典标记的方式或属性的方式,比如用索引字段ix
# print frame.ix[3]

# 精准匹配
val = Series([-1.2, -1.5, -1.7], index=["two", "four", "five"])
frame.index = Series(['one', 'two', 'three', 'four', 'five'])
frame.debt = val  #debt 是啥东东
# print frame
# 为不存在的列赋值存在列中的某个值会创建出一个布尔列。关键字del用于删除列。
frame["eastern"] = frame.state == "Ohio"

del frame["eastern"]       # 只能这样表示  删除列

# 嵌套字典
pop = { "Nevada" : {2001 : 2.4, 2002 : 2.9},
        "Ohio"   : {2000 : 1.5, 2001 : 1.7, 2002 : 3.6}
        }
# 传给DataFrame,它会被解释为:外层字典的键作为列,内层键则作为行索引
frame2 = DataFrame(pop)
# 对该结果进行转置
frame2.T
# 内层字典的键会被合并、排序以形成最终的索引。
frame3 = DataFrame(pop, index=[2001, 2002, 2003])
frame3.index.name = "year"; frame3.columns.name = "state"  #索引和列只有一个名字



# 重新索引
obj = Series([4.5, 7.2, -5.3, 3.6], index=["d", "b", "a", "c"])
# reindex将会根据新索引进行重排。
obj2 = obj.reindex(["a", "b", "c", "d", "e"])
# print obj2
# 将缺失值用0代替
obj2 = obj.reindex(["a", "b", "c", "d", "e"], fill_value= 0)
# print obj2


# 插值处理--Series
obj3 = Series(["blue", "purple", "yellow"], index=[0,2,4])
# 前向填充ffill或pad
obj3.reindex(range(6), method="ffill")
# print a
# 后向填充bfill或backfill
b = obj3.reindex(range(6), method="bfill")
# print b


# 插值处理--DataFrame
import numpy as np
f = DataFrame(np.arange(9).reshape((3,3)), index=["a","c","d"],
              columns=["Ohio", "Texas", "California"])
# 改变行的索引
f2 = f.reindex(["a","b","c","d"], fill_value=9)
# print f2
# 改变列的索引
col = ["Texas", "Utah", "California"]
f3 = f.reindex(columns=col)
# print f3
# 同时改变列和行的索引   不成功
f4 = f.reindex(["a","b","c","d"], method="ffill",
               columns=["Texas", "Utah", "California"])
# print f4


# 丢弃指定轴上的项--Series
mys = Series(np.arange(5.), index=["a","b","c","d","e"])
# print mys
# drop()删除某个索引以及对应的值
mys_new = mys.drop("c")
# print mys_new
mys_new1 = mys.drop(["c","e"])
# print mys_new1

# 丢弃指定轴上的项--DataFrame
data = DataFrame(np.arange(16).reshape((4,4)),
                 index=["Ohio", "Colorado", "Utah", "New York"],
                 columns=["one", "two", "three", "four"])
# 删除某行轴上的值
data1 = data.drop(["Ohio","Utah"], axis=0)    # axis=0代表行
# print data1
# 删除某列轴上的值
data2 = data.drop(["one","three"], axis=1)    # axis=1代表列
# print data2


obj = Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
# 使用is_unique属性可以知道他的值是否是唯一的
obj.index.is_unique
# obj['a']
df = DataFrame(np.random.randn(4, 3), index=['a', 'b', 'a', 'b'])
df.ix["b", 1]
df[1]
# pandas中的索引高级处理:

# 索引、选取和过滤--Series
obj = Series(np.arange(4), index=["a","b","c","d"])
# print obj["b"]
# print obj[1]
# print obj[2:4]
# print obj[["b","a","d"]]
# print obj[[1,3]]
# print obj[obj < 2]
# 利用标签的切片运算与普通的python切片运算不同,其末端是包含的
# print obj["b":"c"]
obj["b":"c"] = 5
# print obj






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值