Pandas之一

NumPy
pandas <<=
数据可视化

Pandas是基于NumPy数组构建的,特别是基于数组的函数和不适用for循环的数据处理,二者最大的不同是,Pandas是专门为处理表格和混杂数据设计的,而NumPy更适合处理统一的数值数组的数据。
Pandas是个比较的库了,第二版里边大约是根据ETL的方式在组织着,并且举了更多的例子,由于篇幅太大,很适用。这里将Pandas分成2篇,一篇基础,包括数据类型、索引、存储与加载,另外一篇是进阶,包括清理、转换、聚合

pandas的数据结构

Series

  • 基本属性与创建

    Series 是一维带标记的数组结构,可以存储任意类型的数据(整数,浮点数,字符串,Python 对象等等)。
    Series有2个属性,一是数据的values,它是一维的数组;二是数据的index,它代表着数据的索引

    obj = pd.Series([4, 7, -3, 6])
    obj.values      # array([4, 7, -3, 6])
    obj.index       #  RangeIndex(start=0, stop=4, step=1)
    

    创建时,可以通过index指明索引:

    obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
    obj2.index   # Index(['d', 'b', 'a', 'c'], dtype='object')
    

    如果 data 是个 ndarray,那么 index 的长度必须跟 data 一致
    如果 index 为空,那么 index 会使用 [0, ..., len(data) - 1]:

    除了通过列表创建,Series还可以通过字典创建。如果 data 是个 dict,如果不给定 index,那么 index 将使用 dict 的 key 排序之后的结果

    sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
    
    obj3 = pd.Series(sdata)
    obj3  
    # Ohio 35000
    # Oregon 16000
    # Texas  71000
    # Utah 5000
    
    states = ['California', 'Ohio', 'Oregon', 'Texas']
    obj4 = pd.Series(sdata, index=states)
    obj4
    # California NaN
    # Ohio 35000
    # Oregon 16000
    # Texas  71000
    

    Series对象本身以及index都有一个name属性,如

    obj4.name = 'population'
    obj4.index.name = 'state'
    

    Series的索引可以通过赋值的方式就地修改

    obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
    
  • 基本使用

    Series跟NumPy的array的使用方式有些类似

    obj2['a']   # -5
    
    obj2['d'] = 6
    
    obj2[['c','a','d']]   
    # c  3 
    # a -5
    # d  6
    
    obj2[obj2 > 0]
    # d  6  
    # b  7  
    # c  3
    
    obj2*2  
    # d  12  
    # b  14
    # a  -10  
    # c    6
    
    np.exp(obj2)
    
    'b' in obj2 
    #True
    

    Seriesd对于缺省数据,可以通过isnull和notnull进行检查

    pd.isnull(obj4)
    pd.notnull(obj4)
    

    与np的array不同,Series进行计算时,会根据索引标签自动对齐数据,这一点类似于sql的join功能

    obj3+obj4  
    
    # California      NaN
    # Ohio              70000.0
    # Oregon        32000.0
    # Texas           142000.0
    # Utah            NaN
    

DataFrame

DataFrame是Pandas的灵魂,如果把Series看成一维的,那它就是二维的,对照Series,它有3个基本属性:数据的values,数据的行索引index,数据的列索引column。可以通过frame.columns、frame.index等访问

  • 创建
    DataFrame(data, index, columns) 中的 data 可以接受很多数据类型,如Numpy数组组成的字典、2维ndarray、另外一个DataFrame

    从 ndarray 或者 list 字典中构造

    data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
                    'year': [2000, 2001, 2002, 2001, 2002, 2003],
                    'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
    
    frame = pd.DataFrame(data, index=['one', 'two', 'three', 'four', 'five', 'six'])
    

    二维数据

    arrData = np.random.randn(2,3)
    df = pd.DataFrame(arrData, index=['a','b'], columns=['job','position'])
    
  • 基本使用

frame.head()            # 对于特别大的DataFrame,head方法会取前5行

frame['state']          # 这种取法,是取的'state'列与index
frame.state               # 同上

frame.loc['one']    # 这种取法,取的是'one'这一行以及column
frame.iloc[0]           # 这是是通过下标进行获取的
frame.loc['one', 'state']   # loc可以放行列2个值

frame['debt'] = np.arange(6)      # 这样是增加一个'debt'列,并赋值
frame['eastern'] = fram.state == 'Ohio'   # 增加一个'eastern'列, 当'state' 为'Ohio'是True,否则为False
del frame['eastern']          # 删除该列

基本功能

reindex

它的作用是创建一个新对象,数据符合新的索引,若没有,则用NaN填充。对Series与DataFrame都适用。
别被它的名字所骗,它本质上是一个复制操作

obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d','b','a','c'])

obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
# a  -5.3
# b   7.2
# c   3.6
# d   4.5
# e   NaN

对于时间序列这样的有序数据,reindex时候,可以做一些插值处理。

obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3.reindex(range(6), method='ffill')

注意:无序数据是不能用ffill的

对于DataFrame,reindex既可以修改index,也可以修改column

frame = pd.DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])

frame2 = frame.reindex(['a', 'b', 'c', 'd'])
frame3 = frame.reindex(columns=['Texas', 'Utah', 'California'])

drop

删除指定轴上的一个或多项,它返回的是一个删除之后的新对象

frame2.drop(['a', 'b'])      # 删除,a,b两行
frame2.drop(['Texas', 'Utah'], axis=1)      # 删除Texas,Utah两列

fill_value

在进行算术运算时候,如果reindx不匹配,就会出现NaN,这时候可以通过传入fill_value参数,来对NaN进行填充

df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)), columns=list('abcd'))
df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)), columns=list('abcde'))

df1 + df2
df1.add(df2, fill_value=0)      # 这是,e就会有值,先对NaN填充成0,然后再计算

算术方法包括:

方法说明
add、radd加法
sub、rsub减法
div、rdiv除法
mul、rmul乘法
pow、rpow指数

注意:r代表着参数反转

apply与applymap

NumPy的ufuncs也适用于操作pandas对象

frame = pd.DataFrame(np.random.randn(4, 3))
np.abs(frame)

另外将函数应用到由某行或者某列所形成的一维数组上,使用apply方法

f = lambda x: x.max() - x.min()
frame.apply(f)      # 对每列执行(沿着axis=0)
frame.apply(f, axis='columns')  # 对每行执行,或者是axis=1

对多常见的数组统计功能,都被实现成了DataFrame的方法,如sum、mean,无需使用apply。

元素级的函数也可以用在DataFrame中,使用applymap方法

format = lambda x: '%.2f' % x
frame.applymap(format)

sort与rank

sort有2种:sort_index与sort_value

frame = pd.DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'], columns=['d', 'a', 'b', 'c'])

frame.sort_index()
frame.sort_index(axis=1, ascending=False)     # 以columns来排序,降序

frame.sort_value(by='b')      # 按b列的值进行排序

rank是为每组分配一个平均排名的方式

obj = pd.Series([7, -5, 6])
obj.rank()        # 它给出的每个value的一种排名

汇总

与Numpy相同,Pandas也集成了一组常用的数据和统计方法。与Numpy不同的是,他们都是基于没有缺失数据的假设而创建的。

这些方法包括:

方法说明
count非NA值的数量
describe汇总统计
min、max最值
argmin、argmax最值的索引位置
quantile计算样本的分位数(0-1)
sum求和
mean平均
median中位数
var方差
std标准差
skew样本的偏度(三阶矩)
kurt样本的峰度(四阶矩)
cumsum累计和
cumprod累计积
diff一阶差分
pct_change百分数变化
corr相关系数
cov协方差矩阵

数据加载与存储

与Numpy相比,pandas对数据的输入输出更看重一些,也增加了对数据库的支持
这里介绍几个常用的:

函数说明
read_csv从csv中读取
read_excel从excel中读取
read_json从json中读取
read_sql读取SQL查询结果

read_csv

! cat example.csv
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world

df = pd.read_csv('example.csv')   # 这时候首行被认为是column,可以通过制定header =None来取消默认
df = pd.read_csv('example.csv', header=None)

通过to_csv方法,可以将数据导出到csv文件中

data.to_csv('data.csv')

大文件的处理

对于很大的文件,可以只读取几行数据,通过指定nrows即可

df = pd.read_csv('example.csv', nrows=5)      # 只读取5行

也可以逐块读取文件,通过指定chunksize

chunker = pd.read_csv('example.csv', chunksize=1000)    # 这时候返回的是TextParse对象,可以迭代

tot = pd.Series([])
for piece in chunker:
    tot = tot.add(piece['key'].value_counts(), fill_value=0)      # value_counts就是每个value出现的count

tot =tot.sort_values()

read_json

!cat example.json
[{"a": 1, "b": 2, "c": 3},
{"a": 4, "b": 5, "c": 6},
{"a": 7, "b": 8, "c": 9}]

data = pd.read_json('example.json')
print(data.to_json())     # 与csv相同可以通过to_json()输出  

read_excel

xlsx = pd.ExcelFile('ex1.xlsx')
data = pd.read_excel(xlsx, 'sheet1')

writer = pd.ExcelWriter('ex2.xlsx')
data.to_excel(writer, 'sheet1')
writer.save

read_sql

可以通过python读数据库的操作,将数据读取到,然后创建成DataFrame 。对这种方式不作介绍了

python sql项目SQLAlchemy可以对sql数据进行抽象,然后通过read_sql可以直接操作

import sqlalchemy as sqla
db = sqla.create_engine("sqlite://mydata.sqlite")     # 这里数据库用的sqlite,其他数据库类似  

data = pd.read_sql("select * from test", db)
# python 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×