pandas笔记一(创建、索引、函数、统计)
pandas10分钟入门,可以查看官网:10 minutes to pandas
也可以查看更复杂的cookbook
- pandas是非常强大的数据分析包,pandas 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包。就好比 Numpy
的核心是 ndarray,pandas 围绕着 Series 和 DataFrame 两个核心数据结构展开 。Series和DataFrame 分别对应于一维的序列和二维表结构。
创建和查看对象
常规导入方式:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Series
- Series 可以看做一个定长的有序字典,它是能够保存任何数据类型(整数,字符串,浮点数,Python对象等)的一维标记数组。
- Series对象包含两个主要的属性:index 和 values。
- 数据可以是Python字典、 ndarray、scalar value标量值(如5)等
- 创建时有没有index都会设置默认下标,但是索引用的是数组时会默认使用创建时的索引
- 创建时还可以指定name名字属性,之后可以修改 rename
ser1 = pd.Series(range(10,15),index=list('ABCDE'))
print(ser1)
# 下标和索引等同
print(ser1['A'])
print(ser1[0])
输出:
A 10
B 11
C 12
D 13
E 14
dtype: int64
10
10
取连续多个数据时,下标取值不包含结束位置,索引切片包括结束位置
print(ser1['A':'D'])
print(ser1[0:3])
输出:
A 10
B 11
C 12
D 13
dtype: int64
A 10
B 11
C 12
dtype: int64
取多个数据、条件筛选(布尔索引)
# 注意里面是一个列表
print(ser1[[0,1,3]])
# 布尔索引
print(ser1[(ser1>12)&(ser1<15)])
DataFrame
DataFrame是二维标记数据结构。 您可以将其视为电子表格或SQL表,或Series对象。 它通常是最常用的pandans对象。 像Series一样,DataFrame接受许多不同种类的输入:
- Dict of 1D ndarrays, lists, dicts, or Series
- 2-D numpy.ndarray
- Structured or record ndarray
- A Series
- Another DataFrame
df1 = pd.DataFrame(np.random.randint(10,50,(3,4)), index=list('ABC'),columns=list('abcd'))
- index是行索引,colums是列索引
- 用字典创建时,键名就是列索引,而且键值可以为列表,会自动补齐
取单行或单列数据,取单个数据
# 列取值,取出的是一个series对象
print(df1['a'])
print(df1['a'].values)
# 取出一行数据的某一行数据,也就是单个数据
print(df1['a']['B']) # 这两个一样
print(df1['a'][1])
取不连续多列,取连续多列(默认不支持连续,需要高级索引)
# 取不连续多列
print(df1[['a','c']])
行索引,可以直接切片,但是默认不能不连续多行取值,下标同理
print('行索引取值##############')
print(df1['A':'A'])
# 取连续多行就是df1['A':'C']
索引和切片操作
高级索引(花式索引)
一般情况用于DataFrame,这里直接略过Series
loc标签索引
df1 = pd.DataFrame(np.random.randint(10,50,(5,4)), index=list('ABCDE'),columns=list('abcd'))
# 取单行,类型是series
print(df1.loc['A'])
print(type(df1.loc['A']))
# 取连续多行,类型是DataFrame
print(df1.loc['A':'C'])
# 如果没有index索引就用下标,可以取连续多行连续多列
print(df1.loc['A':'D','a':'c'])
# 取不连续多行不连续多列
print(df1.loc[['A','C'],['a','c']])
iloc 位置索引
iloc是下标和lo用法一样,但是下标索引左闭右开,loc是包括最后一位
# DataFrame
print(df1.iloc[0:2, 0]) # 注意和df1.loc['A':'C', 'a']的区别
print(df1.loc['A':'C', 'a'])
ix 标签与位置混合索引
博主使用的pandas 0.24.2版本已经弃用.ix了(warning但还能使用),所以也就不写了
- ix是以上二者的综合,既可以使用索引编号,又可以使用自定义索引,要视情况不同来使用,
- 如果索引既有数字又有英文,那么这种方式是不建议使用的,容易导致定位的混乱。
增删改操作
增加操作,修改同理
df1 = pd.DataFrame(np.random.randint(10,20,(3,4)), index=list('ABC'), columns=list('abcd'))
print(df1)
print('增加一列数据是前面四列的和')
df1['e'] = df1['a'] + df1['b'] + df1['c'] + df1['d']
print(df1)
print('增加一行数据是A行的十倍')
df1.loc['D'] = df1.loc['A'] * 10
print(df1)
删除操作:
- drop方法(最好用,可以按行删除):
def drop(self, labels=None, axis=0, index=None, columns=None,
level=None, inplace=False, errors=‘raise’):
当inplace=True时.drop()执行内部删除,不返回任何值,原数据发生改变,默认是返回删除后的数据,不修改原数据 - del方法:删除原始数据,没有返回,del只能删除列不能删除行
- pop方法:删除原始数据并把要删的数据弹出,也就是返回要删除的数据
# 方法有返回值,不修改原数据
# axis=0是删除行,1是删除列
df2 = df1.drop(['A'], axis=0)
df3 = df1.drop(['a','d'], axis=1)
print(df2)
# 删除a列,没有返回
del df2['a']
print(df2)
# 返回要删除的数据,并修改了原始数据,pop也是删除列
df4 = df1.pop('a')
print(df4)
print(df1)
对齐运算(±*/)
- add方法根据列索引进行相加,没有对齐的则设为NaN,有个参数fill_value可以设置默认填充值
- DataFrame对象要行标和列标都相同才相加,如果行标没有相同就是多添加行,不能相加的还是NaN补充
- 其他减乘除方法一样
ser1 = pd.Series(data=range(10,15), index=list('abcde'))
ser2 = pd.Series(data=range(20,25), index=list('cdefg'))
# add根据列索引进行相加,没有对齐的则设为NaN
# print(ser1.add(ser2))
print(ser1.add(ser2, fill_value=10))
# DataFrame相加
df1 = pd.DataFrame(np.arange(11,20).reshape(3,3),columns=list('ABC'))
df2 = pd.DataFrame(np.arange(20,40).reshape(4,5),columns=list('ABCDE'))
print(df1.add(df2, fill_value=10))
输出:
a 20.0
b 21.0
c 32.0
d 34.0
e 36.0
f 33.0
g 34.0
dtype: float64
A B C D E
0 31.0 33.0 35.0 33.0 34.0
1 39.0 41.0 43.0 38.0 39.0
2 47.0 49.0 51.0 43.0 44.0
3 45.0 46.0 47.0 48.0 49.0
索引类型之层级索引(MultiIndex)
- 这个创建了两个索引,也就是层级索引
- levels用来展示两个层级中有哪些索引
- codes说明每一个位置是哪些标签
ser1 = pd.Series(np.random.randint(-10,10,10), index=[list('aabbccddee'), [4,7,1,3,9,2,5,8,0,6]])
# 多重索引
print(ser1)
print(ser1.index)
输出:
a 4 -3
7 -1
b 1 0
3 7
c 9 7
2 -6
d 5 -5
8 8
e 0 0
6 2
dtype: int64
MultiIndex(levels=[['a', 'b', 'c', 'd', 'e'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],
codes=[[0, 0, 1, 1, 2, 2, 3, 3, 4, 4], [4, 7, 1, 3, 9, 2, 5, 8, 0, 6]])
索引取值
print('外层索引取值')
print(ser1['a'])
print('内层索引取值')
print(ser1[:, 4]) # 必须先外层,:意思是所有外层索引
转置
- unstack()函数是将有多层索引的Series对象转成Dataframe对象,外层索引作为行索引
- stack()函数是转Series对象,行索引作为外层索引
ser1 = pd.Series(np.random.randint(-10,10,10), index=[list('aabbccddee'), [1,2,1,2,1,2,1,2,1,2]])
df1 = pd.DataFrame(np.random.randint(-10,10,(4,4)), index=[2,1,3,5], columns=list('abcd'))
# 转dataframe对象
print(ser1.unstack())
# dataframe转series对象,行索引是最外层索引
print(df1.stack())
- df1.T是index和columns互换,也就是行列转置
- 转字典to_dict,转csv,to_csv
pandas函数应用
数据清洗
处理空值
- isnull()、notnull()判断是否为空和判断是否不为空
- dropna()默认删除空值在的行,axis=1删除所在列,根据inplace值决定是对源数据修改与否
- fillna()填充NaN值,需要填参数,可以根据列或者行来填充不同的值
df1 = pd.DataFrame([np.random.randint(10,50,4),[1.1,2.2,3.3], [np.NaN, 1,2,3]])
df1.dropna(axis=1)
# 根据0列和3列填充指定的不同的数据
print(df1.fillna({0:10, 3:100}))
输出:
1 2
0 41.0 47.0
1 2.2 3.3
2 1.0 2.0
0 1 2 3
0 15.0 41.0 47.0 41.0
1 1.1 2.2 3.3 100.0
2 10.0 1.0 2.0 3.0
处理重复数据
删除操作
- duplicated()根据列判断,如果没出现过则是False,出现过的值显示True
- drop_duplicates()的三个参数
- subset=None表示考虑所有列,将这所以列对应值相同的行进行去重。默认值None。subset=[‘B’]表示只考虑’B’这列,将B列对应值相同的行进行去重。
- keep='first’表示保留第一次出现的重复行,是默认值。keep另外两个取值为"last"和False,分别表示保留最后一次出现的重复行和去除所有重复行。
- inplace=True表示直接在原来的DataFrame上删除重复项,而默认值False表示生成一个副本
df2 = pd.DataFrame({'A':['a','b','c','c'],'B':[1,1,2,2]})
print(df2)
print(df2.duplicated('B'))
print(df2.drop_duplicates('A'))
输出:
A B
0 a 1
1 b 1
2 c 2
3 c 2
0 False
1 True
2 False
3 True
dtype: bool
A B
0 a 1
1 b 1
2 c 2
数据替换
- replace的基本结构是:df.replace(to_replace, value) 前面是需要替换的值,后面是替换后的值。
- 使用正则表达式的时候记得后面加 regex=True参数。
df2 = pd.DataFrame({'A':['a','b','c','c'],'B':[1,1,2,2]})
# 将a,c替换成1
print(df2.replace('c', 1))
# 多个指定替换
print(df2.replace({'b':1,'c':2}))
# 指定列中的数据替换成后面的数据
print(df2.replace({'A':'c'}, 'm'))
# 正则替换
print(df2.replace('[a-b]', 'r', regex=True))
输出:
A B
0 a 1
1 b 1
2 1 2
3 1 2
A B
0 a 1
1 1 1
2 2 2
3 2 2
A B
0 a 1
1 b 1
2 m 2
3 m 2
A B
0 r 1
1 r 1
2 c 2
3 c 2
排序
Series和Dataframe都适用
- sort_index():按索引进行排序,默认是升序,ascending=False则是降序
- sort_values():按照值进行排序,参数by是指定哪一行或列,axis默认为0是列,=1是行排序
ser1 = pd.Series(np.random.randint(-10,10,10), index=[4,7,1,3,9,2,5,8,0,6])
df1 = pd.DataFrame(np.random.randint(-10,10,(4,4)), index=[2,1,3,5], columns=list('abcd'))
print(ser1.sort_index(ascending=False)) # 按索引进行排序,默认是升序,ascending=False则是降序
# 这个排序实际上只按照列表第一个值进行排序
print(df1.sort_values(by=[1,2,3,5],axis=1))
自定义函数操作
- apply()将自定义的函数对列或行进行操作,第一个参数是函数(可以是匿名函数),默认axis=0是列,axis=1是行
- applymap()是对单个数据进行操作,apply只能用于计算型函数
df1 = pd.DataFrame(np.random.randint(-10,10,(3,4)))
print(df1)
print('#################')
def func(x):
# print(x)
# 求最大和最小值差
num = np.max(x) - np.min(x)
# print(num)
return num
# axis=1是行,默认是0为列
# print(df1.apply(func=func)) # 这两个是一样的
print(df1.apply(lambda x: np.max(x) - np.min(x)))
def myfunc(x):
# 取的是绝对值
return abs(x)
# 这是对单个参数进行操作
print(df1.applymap(lambda x:abs(x)))
pandas统计(各种函数)
- 可以使用numpy的sum等函数
- pandas也有自带的函数sum()、mean()等
- 默认列求和,axis=1就是行求和
- describe() # 展示各种函数
df1 = pd.DataFrame(np.random.randint(-10,10,(4,4)), index=[2,1,3,5], columns=list('abcd'))
print(df1.sum()) # 求和
print(df1.mean()) # 求均值
print(df1.median()) # 中位数
print(df1.describe()) # 展示各种函数
describe输出:
a b c d
count 4.000000 4.000000 4.000000 4.000000
mean -1.750000 -4.750000 -4.250000 5.000000
std 6.849574 4.349329 6.130525 3.366502
min -10.000000 -9.000000 -10.000000 0.000000
25% -5.500000 -8.250000 -9.250000 4.500000
50% -1.500000 -4.500000 -4.500000 6.500000
75% 2.250000 -1.000000 0.500000 7.000000
max 6.000000 -1.000000 2.000000 7.000000