(九)Python总结笔记:Pandas

Python总结笔记(九)Pandas

pandas数据结构:Series和DataFrame

Series

Series是基础数据结构(一维数组),索引可以像字典一样指定key。字典值乱序,Series有序,可以使用非数字下标索引。

import pandas as pd#导入库
from pandas import DataFrame, Series#引用对象
  1. 构建Series、初始化
  • 初始化Series,不给索引:索引自动从0开始,依次递增。

obj = Series([4, 7, -5, 3])#索引自动从0开始,依次递增。

  • 在初始化同时,给索引
    obj = Series([4, 7, -5, 3], index=[‘d’, ‘b’, ‘a’, ‘c’])#自己设定索引,使用非数字下标索引。

  • 先初始化Series,再给索引

obj = Series([4, 7, -5, 3])
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']#若数量不匹配,会报错

字典初始化Series对象,是有序的,但是无法通过字典构造指定key的顺序。

sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000,'California':1}

obj3 = Series(sdata) # 使用字典初始化Series,但是顺序没有保证。
#解决办法:
states = ['California', 'Ohio', 'Oregon', 'Texas', 'Utah', 'New Jersy']
obj4 = Series(sdata, index=states) # 字典和索引数组结合保证顺序,初始化Series,同时指定索引数组,长度由索引数组决定。

obj.index#查看索引
obj.values#查看值
obj.name = ‘population’ # 给Series起名
obj.index.name = ‘state’ # 给Series的index起名

  1. Series读取(访问)、操作

读取(访问)
根据数字下标索引:obj[1])
根据非数字下标索引:obj[‘b’]
过滤:obj[obj > 0]
判断key(index)是否存在:‘b’ in obj
查看Series的支持方法:dir(obj)
np.exp(obj)或者obj * 2:作用在每个元素上
检测缺失值,返回Series数组。pd.isnull(obj) :缺失返回True、不缺失返回Flase。obj.isnull():缺失返回True,不缺失返回True。
obj3 + obj4:对应索引位置相加,对不上的设置为None

obj.reindex([‘a’, ‘b’, ‘c’, ‘d’, ‘e’]) # 重新指定索引顺序
obj.reindex([‘a’, ‘b’, ‘c’, ‘d’, ‘e’], fill_value=obj.mean()) #重新指定索引顺序,并且定填充值。

obj = Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e']) # 重新指定索引顺序
print(obj2)
obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=obj.mean()) #指定填充值

obj3.reindex(range(6), method=‘ffill’) # 指定填充方式为ffill,对于找不到的值用前一个值填充。

obj3 = Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3.reindex(range(6), method='ffill') # 指定填充方式为ffill,对于找不到的值用前一个值填充。

排序
obj.sort_values() # 根据值排序
obj.sort_index()#根据索引排序

#根据索引排序(不用给定的obj.sort_index()函数)
index = ['d', 'c', 'a', 'b']
obj = Series([4, 7, -3, 2], index=index)
index = sorted(index)
obj = obj.reindex(index)
obj

切片

  • 普通数值下标切片:
index = ['d', 'c', 'a', 'b', 'f', 'g']
obj = Series([4, 7, -3, 2, 9, 3], index=index)
x = obj[1:5] #普通数值索引: 左闭右开区间,并且x没有复制生成一个新的Series。
x[2] = 10#切片引用,修改了原来的值
obj
x

注意:对Series切片是引用类型,与数组不同(数组:不引用,修改不了值)。

x1=[1,2,3,4,5,6]
x2=x1[1:4]
x2[0]=100#数组修改值,未改变原来的,不是引用。
print(x1)
print(x2)
  • 非数值切片:obj[‘c’:‘f’:1或者-1] #起始位置,结束位置,步长方向(若为负数代表反方向)
#切片-索引:
print(obj['c':'f'])#起始位置,结束位置,步长方向
print(obj['b':'d':-1]) # 闭区间-1代表反方向

DataFrame

本质上是一个二维数组,用index定位行,用columns定位列。

#           col_1 col_2 ... col_n
#  index_1  x11   x12       x1n 
#  index_2  x21   x22       x2n
#  ...
#  index_m  xm1   xm2       xmn
#
#        房价  人口 GDP
#  上海  ...
#  北京
#  天津
  1. 初始化

创建列无序:

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]} # key代表列的名字,对应的数组就是这个列的值。(行采用默认的数字索引。)
#使用字典,导致列无序
frame = DataFrame(data)
frame

创建列无序:
frame = DataFrame({‘b’: [4, 7, -3, 2], ‘a’: [0, 1, 0, 1]})

指定列的顺序:DataFrame(data, columns=[‘year’, ‘state’, ‘pop’])

创建列有序:

frame2 = DataFrame(data, 
                   columns=['year', 'state', 'pop', 'debt'], # 匹配不到的行和列设置为None
                   index=['one', 'two', 'three', 'four', 'five']) # 使用index指定列

将列变成索引:

frame = DataFrame({'year': [2000, 2001, 2002, 2003, 2004],
                   'sales': [1500, 3700, 2400, 2900, 4900]})
frame
frame.set_index('year') # 将列变成索引
  1. 访问

快速访问列:.+属性名 print(frame2.year) #.+属性名 快速访问列,不管是一行还是一列,返回的是一个Series。

索引访问:print(frame2[‘pop’]) #索引访问,和普通二维数组非常不一样!!!

切片访问:数字索引,iloc用数字索引访问行和列(左闭右开区间)

print(frame2.iloc[1,]) # 访问第1行
print(frame2.iloc[:,2]) # 访问第2列pop
print(frame2.iloc[1:3, 0:3]) #第1/2行,第0/1/2列切片

切片访问:名字索引,指定行范围或者某一列。loc用名字索引访问行和列(闭区间)

print(frame2.loc['one',])
print(frame2.loc['one':'three',])
print(frame2.loc[:,'state'])
print(frame2.loc['two':'four','year':'debt'])

花式索引:使用iloc或loc选择指定的行列组合

frame2.iloc[[0, 1, 3], [0, 2]]
frame2.loc[['one', 'three', 'four'], ['state', 'pop']]
  1. 赋值

对某一列赋值,作用在所有元素上 frame2[‘debt’] = 100

赋值数组,长度必须一致 frame2[‘debt’] = np.arange(5)

据索引名字匹配行,匹配不到的索引自动扔掉 frame2[‘debt’] = Series([-1.2, -1.5, -1.7, 2], index=[‘two’, ‘four’, ‘five’, ‘six’])

增加一列进行赋值
frame2[‘eastern’] = (frame2.state == ‘Ohio’)
frame2[‘big’] = (frame2[‘pop’] > 2.5)

注意: 数组a[row][col];但是在df中 a[row,col],a[col]表示单独一列。

重新定义索引:frame2 = frame.reindex([‘a’, ‘b’, ‘c’, ‘d’]) # 数量不用匹配,没有的自动填充NaN。

frame2 = frame.reindex(['a', 'b', 'c', 'd']) # 数量不用匹配,没有的自动填充NaN。
states = ['Texas', 'Utah', 'California']
frame3 = frame2.reindex(columns=states) # 重新指定行/列索引顺序

根据index删除值:默认axis=0按行

data = DataFrame(np.arange(16).reshape((4, 4)),
                 index=['Ohio', 'Colorado', 'Utah', 'New York'],
                 columns=['one', 'two', 'three', 'four'])
print(data)
print(data.drop(['Colorado', 'Ohio']))
print(data.drop('two', axis=1))
print(data.drop(['two', 'four'], axis=1))

数据过滤-按列过滤

data[data.three < 10] # three列上值大于等于10的行扔掉,小于的保留。
data.loc[data.three < 5, ]

赋值: data[data > 10] = 0

注意:定位行和列[],调用方法:()

  1. DataFrame和Series的计算

加法:data + 100

每一行减去其中一行:

frame = DataFrame(np.arange(12.).reshape((4, 3)),
                  columns=list('bde'),
                  index=['Utah', 'Ohio', 'Texas', 'Oregon'])
s = frame.iloc[0]#取一行
print(frame)
print(s)
print(frame - s) # 每一行减去对应的s,本质上每一行在对应的索引位置上相减。

选取几列加上对应数值:

s2 = Series(range(3), index=['b', 'e', 'f'])
print(s2)
print(frame + s2)

每列加减操作

# 行上操作的特殊性
s3 = frame['d']#找到一列
print(s3)
#每个列不可以直接加减。
frame.sub(s3, axis=0) # 每一列都沿着行的方向,根据index做减法。

绝对值——元素级函数

frame = DataFrame(np.random.randn(4, 3),
                  columns=list('bde'),
                  index=['Utah', 'Ohio', 'Texas', 'Oregon'])
print(frame)
np.abs(frame) # 元素级函数

自己定义函数,并应用。

f = lambda x: x.max() - x.min()#数组最大值-最小值
frame.apply(f) # 每一列应用f 默认axis=0 每一列
frame.apply(f, axis=1)# 每一行
def f(x):
    return Series([x.min(), x.max()], index=['min', 'max'])#返回Series
frame.apply(f, axis=1)#对某一列
format = lambda x: '%.2f' % x 
frame.applymap(format)#对每个元素进行操作
frame['e'].map(format)
  1. 排序

按行索引排序

# 排序
frame = 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)
按某列值排序 frame.sort_values(by=‘b’, ascending=False)
列a相等时用b排序frame.sort_values(by=[‘a’, ‘b’]) # 参考sql的order by, a相等时用b排序
根据某行索引,调整排序顺序 frame.sort_values(by=[2], axis=1) # 根据行数字索引为2,调整排序顺序
rank函数(与出现位置有关的排序)

求每列sum print(df.sum()) # 沿着行的方向对每一列求sum
求每行sum print(df.sum(axis=1))# 沿着列的方向
累加 df.cumsum() # 累加
每一列的统计信息 df.describe() # 每一列的统计信息
相关系数和协方差,使用tushare

  1. 缺失值处理
    有NA的行删除 data.dropna() #有NA的行删除
data = DataFrame([[1., 6.5, 3.],
                  [1., 7, NA],
                  [NA, NA, NA],
                  [NA, 6.5, 3.]])
data
cleaned = data.dropna() # 有NA的行删除
cleaned

只有某一行全部是NA才删除 data.dropna(how=‘all’) #只有某一行全部是NA才删除。

至少有3个值不为NA的列被保留,其它删除 data.dropna(thresh=3, axis=1) #至少有3个值不为NA的列被保留,其它删除

  1. 数据合并
# outer: 左右,左-,-右
# inner:左右
# left: 左右,左-
# right: 左右,-右

默认根据名字相同的列作合并

df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                 'data1': range(7)})
df2 = DataFrame({'key': ['a', 'b', 'd'],
                 'data2': range(3)})
print(df1)
print(df2)
pd.merge(df1, df2) # 默认根据名字相同的列作合并,等价pd.merge(df1, df2, on='key')
pd.merge(df1, df2, on='key')

分别指定用于合并的参考列

df3 = DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                 'data1': range(7)})
df4 = DataFrame({'rkey': ['a', 'b', 'd'],
                 'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey') # 分别指定用于合并的参考列

指定连接方式 pd.merge(df1, df2, how=‘outer’) # 指定连接方式

多个列的合并

left = DataFrame({'key1': ['foo', 'foo', 'bar'],
                  'key2': ['one', 'two', 'one'],
                  'lval': [1, 2, 3]})

right = DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
                   'key2': ['one', 'one', 'one', 'two'],
                   'rval': [4, 5, 6, 7]})
pd.merge(left, right, on=['key1', 'key2'], how='outer') # 基于多个列的合并

重名列可以指定合并后的后缀 pd.merge(left, right, on=‘key1’, suffixes=(’_left’, ‘_right’)) # 重名列可以指定合并后的后缀

使用right的索引参与合并

left1 = DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],
                   'value': range(6)})
right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
print(left1)
print(right1)
pd.merge(left1, right1, left_on='key', right_index=True) # 使用right的索引参与合并

join默认使用索引合并

left2 = DataFrame([[1., 2.], [3., 4.], [5., 6.]],
                  index=['a', 'c', 'e'],
                  columns=['Ohio', 'Nevada'])
right2 = DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],
                   index=['b', 'c', 'd', 'e'],
                   columns=['Missouri', 'Alabama'])
left2.join(right2, how='outer') # join默认使用索引合并

一次合并多个DataFrame,默认使用全连接

another = DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],
                    index=['a', 'c', 'e', 'f'],
                    columns=['New York', 'Oregon'])
left2.join([right2, another]) # 一次合并多个DataFrame,默认使用全连接。

连接

s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])
pd.concat([s1, s2, s3]) # 默认沿着行的方向连接——串起来
pd.concat([s1, s2, s3], axis=1) # 在列方向上连接,行索引没有识别到自动为nan

条件搜索

a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],
          index=['f', 'e', 'd', 'c', 'b', 'a'])
b = Series(np.arange(len(a), dtype=np.float64),
           index=['f', 'e', 'd', 'c', 'b', 'a'])
b[-1] = np.nan
np.where(pd.isnull(a), b, a) # 条件搜索, 根据where筛选,如果a对应位置的元素为None就选b,否则保留a的值

填补

df1 = DataFrame({'a': [1., np.nan, 5., np.nan],
                'b': [np.nan, 2., np.nan, 6.],
                'c': range(2, 18, 4)})
df2 = DataFrame({'a': [5., 4., np.nan, 3., 7.],
                 'b': [np.nan, 3., 4., 6., 8.]})
print(df1)
print(df2)
df1.combine_first(df2)#df1对应为空,则选取df2对应项填补
  1. 其他需要的知识点
    pivot和melt
    值替换
    数据切割
    排列组合和随机采样–数据d5、做交叉验证asan

Pandas画图

线型图

# 线型图
s = Series(np.random.randn(1000).cumsum(), index=np.arange(0, 100, 0.1))
s.plot()

多条线型图

df = DataFrame(np.random.randn(100, 4).cumsum(0),
               columns=['A', 'B','C', 'D'],
               index=np.arange(0, 100, 1))
df.plot() # 每一列对应一条曲线

柱状图

# 柱状图 - Series
data = Series(np.random.rand(10), index=list('abcdefghij'))
fig, axes = plt.subplots(2, 1)
data.plot(kind='bar', ax=axes[0])
data.plot(kind='barh', ax=axes[1])

多个柱状图

# 柱状图(并列) - Pandas
df = DataFrame(np.random.rand(6, 4),
               columns=['A', 'B', 'C', 'D'],
               index=['one', 'two','three', 'four', 'five', 'six'])
df.plot(kind='bar')
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laura_Wangzx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值