pandas
- 处理表格等文件/数据库
- 获取数据(自定义,未来爬虫获取)
- 对数据逻辑处理,pandas+numpy
- 保存数据
- 支持文件存取操作,支持数据库(sql)、html、json、pickle、csv(txt、excel)、sas、stata、hdf等。
import pandas as pd
import numpy as np
# 约定俗成
Series
Series的创建方式
# pd.Series([1, 2, 3, 4])
# 效果相同,只是上面的dtype是int64 (占用的字节数更大)
s1 = pd.Series(np.array([1, 2, 3, 4]))
print(s1)
print(s1[1])
0 1
1 2
2 3
3 4
dtype: int32
2
s2 = pd.Series([1,2,3,4], index=['a','b', 'c', 'd']) # 指定索引
print(s2)
print(s2['b']) # 两种方式都可以取值
print(s2[1])
a 1
b 2
c 3
d 4
dtype: int64
2
2
s3 = pd.Series({"a":1, 'b':2})
s4 = pd.Series(0, index=['a','b'])
print(s3)
print(s4)
a 1
b 2
dtype: int64
a 0
b 0
dtype: int64
series处理缺失值 nan
st = {"hehe":18, 'haha':19, 'jinmi':20, 'lily':23}
pd.Series(st)
a = ['hehe', 'haha', 'lucy', 'jinmi']
s1 = pd.Series(st, index=a) #### nan是float类型, 因此其余的值为了迁就nan, 就必须从int转成float
s1
hehe 18.0
haha 19.0
lucy NaN
jinmi 20.0
dtype: float64
s1.dropna(inplace=True) ### 第一种处理方式:直接删掉nan所在行,inplace=True代表删除原数据
s1
hehe 18.0
haha 19.0
jinmi 20.0
dtype: float64
s1.fillna(0) #### 第二种处理方式: fillna进行nan的填充,现在填充0
hehe 18.0
haha 19.0
lucy 0.0
jinmi 20.0
dtype: float64
s1.isnull() # 如果是Nan,会返回True
hehe False
haha False
lucy True
jinmi False
dtype: bool
series的特性
- 按照索引进行计算,如果没有相应的,则是NaN
- 其余和numpy类似
s1 = pd.Series(np.array([1,2,3,4]))
s2 = pd.Series([5,6,7,8,9])
s1 + s2
0 6.0
1 8.0
2 10.0
3 12.0
4 NaN
dtype: float64
s1 > 3
0 False
1 False
2 False
3 True
dtype: bool
s1[s1>3]
3 4
dtype: int32
s1.mean() # 函数也是一样
2.5
DataFrame
创建方式
df1 = pd.DataFrame({'one':[1,2,3,4], 'two':[5,6,7,8]})
|
one |
two |
0 |
1 |
5 |
1 |
2 |
6 |
2 |
3 |
7 |
3 |
4 |
8 |
内置方法
属性 |
详解 |
dtype |
查看数据类型 |
index |
查看行序列或者索引 |
columns |
查看各列的标签 |
values |
查看数据框内的数据,也即不含表头索引的数据 |
describe |
查看数据每一列的极值,均值,中位数,只可用于数值型数据 |
transpose |
转置,也可用T来操作 |
sort_index |
排序,可按行或列index排序输出 |
sort_values |
按数据值来排序 |
# 获取每一列的数据类型
df1.dtypes
one int64
two int64
dtype: object
# 获取索引
df1.index
RangeIndex(start=0, stop=4, step=1)
# 获取列标题
df1.columns
Index(['one', 'two'], dtype='object')
# 获取值
df1.values
df1.values
df1.values
array([[1, 5],
[2, 6],
[3, 7],
[4, 8]], dtype=int64)
# 把这些值获取为list格式
df1.index.to_list()
[0, 1, 2, 3]
# 生成描述性统计
df1.describe()
|
one |
two |
count |
4.000000 |
4.000000 |
mean |
2.500000 |
6.500000 |
std |
1.290994 |
1.290994 |
min |
1.000000 |
5.000000 |
25% |
1.750000 |
5.750000 |
50% |
2.500000 |
6.500000 |
75% |
3.250000 |
7.250000 |
max |
4.000000 |
8.000000 |
# 标题互换
df1.transpose()
|
0 |
1 |
2 |
3 |
one |
1 |
2 |
3 |
4 |
two |
5 |
6 |
7 |
8 |
# 按照index排序,为True则是正序
df1.sort_index(ascending=False)
|
one |
two |
3 |
4 |
8 |
2 |
3 |
7 |
1 |
2 |
6 |
0 |
1 |
5 |
# 对'tesla'的值进行排序,
df1.sort_values(by=['two'], ascending=True)
|
one |
two |
0 |
1 |
5 |
1 |
2 |
6 |
2 |
3 |
7 |
3 |
4 |
8 |
DataFrame 的取值
df1 = pd.DataFrame({'a':[1, 11], 'b':[2, 22]}, index=['a', 'b'])
df1
df1['a'][1] # 需要先取列标题,再取行标题,这种取值,用两种都可以
11
df1[:][0:1]
# 按照索引取值,只能按设定的索引取
df1.loc['a']
a 1
b 2
Name: a, dtype: int64
# 类似于numpy取值,只能按照0,1,2,3这种索引取
df1.iloc[0]
a 1
b 2
Name: a, dtype: int64
DataFrame 读取excel表格的数据
- xlsx格式是压缩后的,使用csv的可以直接用notepade之类的编辑器查看数据
movies = pd.read_csv('douban_movie.csv')
movies.head() # 默认显示前5条,也可以在里面加条数
|
名字 |
投票人数 |
类型 |
产地 |
上映时间 |
时长 |
年代 |
评分 |
首映地点 |
0 |
肖申克的救赎 |
692795.0 |
剧情/犯罪 |
美国 |
1994-09-10 00:00:00 |
142 |
1994 |
9.6 |
多伦多电影节 |
1 |
控方证人 |
42995.0 |
剧情/悬疑/犯罪 |
美国 |
1957-12-17 00:00:00 |
116 |
1957 |
9.5 |
美国 |
2 |
美丽人生 |
327855.0 |
剧情/喜剧/爱情 |
意大利 |
1997-12-20 00:00:00 |
116 |
1997 |
9.5 |
意大利 |
3 |
阿甘正传 |
580897.0 |
剧情/爱情 |
美国 |
1994-06-23 00:00:00 |
142 |
1994 |
9.4 |
洛杉矶首映 |
4 |
霸王别姬 |
478523.0 |
剧情/爱情/同性 |
中国大陆 |
1993-01-01 00:00:00 |
171 |
1993 |
9.4 |
香港 |
movies.to_csv('aa.csv', index=False) # 因为读出来之后,会默认加上一行索引,但是保存并不需要,所以要用index=False去掉
res = pd.read_html('https://baike.baidu.com/item/NBA%E6%80%BB%E5%86%A0%E5%86%9B/2173192?fr=aladdin') #### 相当于request.get(),区别是只会读取网页中的表格数据
nba_champion = res[0] # 因为得到的是一个列表
nba_champion
|
0 |
1 |
2 |
3 |
4 |
5 |
0 |
年份 |
比赛日期 |
冠军 |
总比分 |
亚军 |
FMVP |
1 |
1947 |
4.16-4.22 |
费城勇士队 |
4-1 |
芝加哥牡鹿队 |
无 |
2 |
1948 |
4.10-4.21 |
巴尔的摩子弹队 |
4-2 |
费城勇士队 |
无 |
3 |
1949 |
4.4-4.13 |
明尼阿波利斯湖人队 |
4-2 |
华盛顿国会队 |
无 |
4 |
1950 |
4.8-4.23 |
明尼阿波利斯湖人队 |
4-2 |
塞拉库斯民族队 |
无 |
nba_champion.columns = nba_champion.iloc[0] # 让列标题变成第一行的数据
nba_champion.drop([0], inplace=True) # 再删掉原本的第一行
nba_champion.head()
|
年份 |
比赛日期 |
冠军 |
总比分 |
亚军 |
FMVP |
1 |
1947 |
4.16-4.22 |
费城勇士队 |
4-1 |
芝加哥牡鹿队 |
无 |
2 |
1948 |
4.10-4.21 |
巴尔的摩子弹队 |
4-2 |
费城勇士队 |
无 |
3 |
1949 |
4.4-4.13 |
明尼阿波利斯湖人队 |
4-2 |
华盛顿国会队 |
无 |
4 |
1950 |
4.8-4.23 |
明尼阿波利斯湖人队 |
4-2 |
塞拉库斯民族队 |
无 |
5 |
1951 |
4.7-4.21 |
罗切斯特皇家队 |
4-3 |
纽约尼克斯队 |
无 |
##### 统计各个球队获取总冠军的次数
nba_champion.groupby('冠军').groups # 用groups是获取夺冠的索引
{'休斯顿火箭队': Int64Index([48, 49], dtype='int64'),
'克里夫兰骑士队': Int64Index([70], dtype='int64'),
...}
nba_champion.groupby('冠军').size() # size是统计次数
冠军
休斯顿火箭队 2
克里夫兰骑士队 1
...
nba_champion.groupby('冠军').size().sort_values(ascending=False).head() # ascending=False代表降序
冠军
波士顿凯尔特人队 17
洛杉矶湖人队 11
芝加哥公牛队 6
圣安东尼奥马刺队 5
明尼阿波利斯湖人队 5
金州勇士队 4
dtype: int64
nba_champion.groupby(['冠军', 'FMVP']).size() # 也可以对多个列进行分组
处理缺失值
test_data = '''
5.1,,1.4,0.2
4.9,3.0,1.4,0.2
4.7,3.2,,0.2
7.0,3.2,4.7,1.4
6.4,3.2,4.5,1.5
6.9,3.1,4.9,
,,,
'''
from io import StringIO
test_data = StringIO(test_data) # office把这个字符串读入内存
df = pd.read_csv(test_data) # 再处理成csv格式
df
|
5.1 |
Unnamed: 1 |
1.4 |
0.2 |
0 |
4.9 |
3.0 |
1.4 |
0.2 |
1 |
4.7 |
3.2 |
NaN |
0.2 |
2 |
7.0 |
3.2 |
4.7 |
1.4 |
3 |
6.4 |
3.2 |
4.5 |
1.5 |
4 |
6.9 |
3.1 |
4.9 |
NaN |
5 |
NaN |
NaN |
NaN |
NaN |
test_data = '''
c1,c2,c3,'c4'
5.1,,1.4,0.2
4.9,3.0,1.4,0.2
4.7,3.2,,0.2
7.0,3.2,4.7,1.4
6.4,3.2,4.5,1.5
6.9,3.1,4.9,
,,,
'''
from io import StringIO
test_data = StringIO(test_data) # office把这个字符串读入内存
df = pd.read_csv(test_data) # 再处理成csv格式
# df.columns = ['c1', 'c2', 'c3', 'c4'] # 可以使用这个添加列标题,但是会覆盖掉最上面一排
df
|
c1 |
c2 |
c3 |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
6 |
NaN |
NaN |
NaN |
NaN |
# 删除带有缺失值的行,这里的0代表行,1代表列
df.dropna(axis=0)
|
c1 |
c2 |
c3 |
'c4' |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1. |
# 把每一列至少有6个正常数据的值打印出来
df.dropna(thresh=6, axis=1)
|
c1 |
0 |
5.1 |
1 |
4.9 |
2 |
4.7 |
3 |
7.0 |
4 |
6.4 |
5 |
6.9 |
6 |
NaN |
# 打印列标题
df.columns
Index(['c1', 'c2', 'c3', 'c4'], dtype='object')
# 把c2列中没有缺失值的值打印出来
df.dropna(subset=['c2'])
|
c1 |
c2 |
c3 |
'c4' |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
# 把缺失值全部赋值为0
df.fillna(value=0)
|
c1 |
c2 |
c3 |
'c4' |
0 |
5.1 |
0.0 |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
0.0 |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
0.0 |
6 |
0.0 |
0.0 |
0.0 |
0.0 |
合并数据
df1 = pd.DataFrame(np.zeros((3, 4)))
df1
|
0 |
1 |
2 |
3 |
0 |
0.0 |
0.0 |
0.0 |
0.0 |
1 |
0.0 |
0.0 |
0.0 |
0.0 |
2 |
0.0 |
0.0 |
0.0 |
0.0 |
df2 = pd.DataFrame(np.ones((3, 4)))
df2
|
0 |
1 |
2 |
3 |
0 |
1.0 |
1.0 |
1.0 |
1.0 |
1 |
1.0 |
1.0 |
1.0 |
1.0 |
2 |
1.0 |
1.0 |
1.0 |
1.0 |
# 合并两个数据,但是这里的axis=0表示根据列合并,1表示根据行合并
pd.concat((df1, df2), axis=0)
|
0 |
1 |
2 |
3 |
0 |
0.0 |
0.0 |
0.0 |
0.0 |
1 |
0.0 |
0.0 |
0.0 |
0.0 |
2 |
0.0 |
0.0 |
0.0 |
0.0 |
0 |
1.0 |
1.0 |
1.0 |
1.0 |
1 |
1.0 |
1.0 |
1.0 |
1.0 |
2 |
1.0 |
1.0 |
1.0 |
1.0 |
高级(了解)
where,apply
举例
# 首先是拿到日期
dates = pd.date_range('2019-01-01', periods=7)
# 从2019-01-01开始,计算7天
dates
DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
'2019-01-05', '2019-01-06', '2019-01-07'],
dtype='datetime64[ns]', freq='D')
# 再拿到商品名称
goods_list = ['tesla', 'transformer', 'chongqiwawa', 'masaladi']
# 再获取商品价格信息
prices = np.random.rand(7, 4)
# 约定俗成df
# 里面的信息 竖标题 横标题
df = pd.DataFrame(prices, index=dates, columns=goods_list)
df
|
tesla |
transformer |
chongqiwawa |
masaladi |
2019-01-01 |
0.205269 |
0.641582 |
0.255601 |
0.841732 |
2019-01-02 |
0.588804 |
0.389713 |
0.504048 |
0.806115 |
2019-01-03 |
0.972583 |
0.819804 |
0.181066 |
0.668763 |
2019-01-04 |
0.474313 |
0.663190 |
0.242855 |
0.730709 |
2019-01-05 |
0.260843 |
0.218108 |
0.473378 |
0.364885 |
2019-01-06 |
0.486229 |
0.906976 |
0.768838 |
0.688883 |
2019-01-07 |
0.806346 |
0.476548 |
0.259264 |
0.733109 |
# 存入excel中
df.to_excel('test.xlsx')