赞
踩
Numpy,Pandas,Matplotlib
(文末送读者福利)
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
ndarray为多维数组。
# 创建一维数据 np.array([1,2,3]) # 创建二维数组 np.array([[1,2,3],['a','b','c']]) 输出: array([['1', '2', '3'], ['a', 'b', 'c']], dtype='<U11') # 使用matplotlib.pyplot获取一个numpy数组,数据来源于一张图片。 # 操作该numpy数据会同步到图片中 import matplotlib.pyplot as plt img_arr = plt.imread('./cat.jpg') plt.imshow(img_arr) plt.imshow(img_arr - 100) # 打印对象属性 type(img_arr) 输出: numpy.ndarray
numpy
默认ndarray
的所有元素的类型是相同的str > float > int
使用np的routines函数创建
# 等差数列 np.linspace(1,100,num=10) 输出: array([ 1., 12., 23., 34., 45., 56., 67., 78., 89., 100.]) np.arange(0,10,2) 输出: array([0, 2, 4, 6, 8]) # 随机因子:表示的是一个无时无刻都在变化的数值,一般指时间。若随机因子不变,输出的结果不变 np.random.seed(10) np.random.randint(0,100,size=(4,5)) 生成0到1的随机数,左闭右开 np.random.seed(3) np.random.random(size=(3,4))
np.random.seed(10) random_arr = np.random.randint(0,100,size=(4,5)) # ndim:维度 random_arr.ndim 输出: 2 # shape:形状(各维度的长度) random_arr.shape 输出: (4, 5) img_arr.shape 输出: (626, 413, 3) # size:总长度 random_arr.size 输出: 20 # dtype:元素类型 random_arr.dtype 输出: dtype('int32')
一维与列表完全一致,多维同理
arr = np.random.randint(1,100,size=(3,4)) arr # 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 打印第二行数据 arr[1] 输出: array([90, 94, 30, 9]) # 修改数据 arr[1] = 10 arr[1] 输出: array([10, 10, 10, 10]) arr[1] = [90, 94, 30, 9] arr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]])
arr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 获取二维数组前两行 arr[0:2] 输出: array([[10, 16, 65, 29], [90, 94, 30, 9]]) # 获取二维数组前两列 # 逗号左边为第一个维度,右边为第二个维度 arr[:,0:2] 输出: array([[10, 16], [90, 94], [74, 1]]) # 获取二维数组前两行和前两列数据 arr[0:2,0:2] 输出: array([[50, 52], [10, 10]]) # 将数据反转,例如[1,2,3]---->[3,2,1],"::"代表整行 # 行反转 arr[::-1] 输出: array([[74, 1, 41, 37], [90, 94, 30, 9], [10, 16, 65, 29]]) # 列反转 arr[:,::-1] 输出: array([[29, 65, 16, 10], [ 9, 30, 94, 90], [37, 41, 1, 74]]) # 行列反转 arr[::-1,::-1] 输出: array([[37, 41, 1, 74], [ 9, 30, 94, 90], [29, 65, 16, 10]]) # 同理可将图片进行反转 # 图片三维分别表示:img_arr(行,列,颜色) plt.imshow(img_arr[:,::-1,:]) # 对图片进行裁剪 plt.imshow(img_arr[50:450,100:300,:])
arr.reshape()
函数,注意参数是一个tuplearr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 将多维数组变形成一维数组 arr.reshape((1,12)) 输出: array([[10, 16, 65, 29, 90, 94, 30, 9, 74, 1, 41, 37]]) arr.reshape((12,1)) 输出: array([[10], [16], [65], [29], [90], [94], [30], [ 9], [74], [ 1], [41], [37]]) 将一维数组变为二维数组 arr.reshape((-1,3)) 输出: array([[10, 16, 65], [29, 90, 94], [30, 9, 74], [ 1, 41, 37]])
arr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 一维,二维,多维数组的级联 # axis=0表示列,axis=1表示行 np.concatenate((arr,arr),axis=1) 输出: array([[10, 16, 65, 29, 10, 16, 65, 29], [90, 94, 30, 9, 90, 94, 30, 9], [74, 1, 41, 37, 74, 1, 41, 37]]) # 合并照片 img_arr = plt.imread('./cat.jpg') plt.imshow(img_arr) arr_3 = np.concatenate([img_arr,img_arr,img_arr],axis=1) arr_9 = np.concatenate((arr_3,arr_3,arr_3),axis=0) plt.imshow(arr_9)
arr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 求arr中所有元素之和 arr.sum(axis=None) 输出: 496 # 求arr中每列之合 arr.sum(axis=0) 输出: array([174, 111, 136, 75]) # 求arr中每行之合 输出: array([120, 223, 153]) # 最大最小值 arr.max(axis=None) 输出: 94 # 打印arr中每列的最大值:np.max/ np.min arr.max(axis=0) 输出: array([90, 94, 65, 37]) # 打印arr中每行的最大值 arr.max(axis=1) 输出: array([65, 94, 74]) # 打印arr中的平均值 arr.mean(axis=None) 输出: 41.3 # 打印arr中的每列平均值 arr.mean(axis=0) 输出: array([58, 37, 45.33333333, 25]) # 打印arr中的每行平均值 arr.mean(axis=1) 输出: array([30, 55.75, 38.25])
np.sort()
与ndarray.sort()
都可以,但有区别:
np.sort()
不改变输入ndarray.sort()
本地处理,不占用空间,但改变输入arr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 对arr每列排序 np.sort(arr,axis=0) 输出: array([[10, 1, 30, 9], [74, 16, 41, 29], [90, 94, 65, 37]]) arr 输出: array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]]) # 对arr每列排序 arr.sort(axis=0) arr 输出: array([[10, 1, 30, 9], [74, 16, 41, 29], [90, 94, 65, 37]]) # 对arr每行排序 arr.sort(axis=0) arr 输出: array([[ 1, 9, 10, 30], [16, 29, 41, 74], [37, 65, 90, 94]])
Pandas Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型。
pandas.Series( data, index, dtype, name, copy)
# 使用列表创建Series Series(data=[1,2,3]) 输出: 0 1 1 2 2 3 dtype: int64 索引:0,1,2 数据:1,2,3 数据类型:int64 # 指定索引值,显示索引 Series(data=[1,2,3],index = ["x", "y", "z"]) 输出: x 1 y 2 z 3 dtype: int64 # 使用 key/value 对象,类似字典来创建 Series: Series(data={'x':1,'y':2,'z':3}) 输出: x 1 y 2 z 3 dtype: int64 # 若只需字典中的一部分数据,只需要指定需要数据的索引即可 Series(data={'x':1,'y':2,'z':3}, index = ['x','z']) 输出: x 1 z 3 dtype: int64 # 设置 Series 名称参数 Series(data={'x':1,'y':2,'z':3}, index = ['x','z'],name = 'Series_Name') 输出: x 1 z 3 Name: Series_Name, dtype: int64
使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的是一个Series类型)。
显式索引:
- 使用index中的元素作为索引值 - 使用s.loc[](推荐):注意,loc中括号中放置的一定是显示索引 s = Series([1,2,3],index=['a','b','c']) s[1] 输出: 2 s[[1,2]] 输出: b 2 c 3 dtype: int64 s['a'] 输出: 1 s.a 输出: 1 s.loc['a'] 输出: 1 s.loc[['a','b']] 输出: a 1 b 2 dtype: int64
隐式索引:
- 使用整数作为索引值, - 使用.iloc[](推荐):iloc中的中括号中必须放置隐式索引 s = Series([1,2,3],index=['a','b','c']) # 隐式索引为右开区间,最后一个索引不引用 s[1:2] 输出: b 2 dtype: int64 # 显式索引为右开区间,最后一个索引引用 s['a':'b'] 输出: a 1 b 2 dtype: int64
s = Series([1,2,3,3,2,4]) # 使用s.head(),tail()分别查看前n个和后n个值 s.head(2) 输出: 0 1 1 2 dtype: int64 # 对Series元素进行去重 s.unique() 输出: array([1, 2, 3, 4], dtype=int64)
# 在运算中自动对齐不同索引的数据,当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况 # 使得两个Series进行相加 s1 = Series([1,2,3],index=['a','b','c']) s2 = Series([1,2,3],index=['a','d','c']) s = s1 + s2 s 输出: a 2.0 b NaN c 6.0 d NaN dtype: float64 # 可以使用pd.isnull(),pd.notnull()或s.isnull(),notnull()函数检测缺失数据 s[[0,1]] 输出: a 2.0 b NaN dtype: float64 s[['a','b']] 输出: a 2.0 b NaN dtype: float64 s[[True,False,True,False]] 输出: a 2.0 c 6.0 dtype: float64 s.isnull() 输出: a False b True c False d True dtype: bool s.notnull() 输出: a True b False c True d False dtype: bool # 打印出不为空值的数据 s[s.notnull()] 输出: a 2.0 c 6.0 dtype: float64
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
DataFrame 构造方法如下:
pandas.DataFrame( data, index, columns, dtype, copy)
# 使用列表创建 df = DataFrame(data=[['a',1],['y',2],['z',3]],columns=['k','v']) df 输出: k v 0 a 1 1 y 2 2 z 3 # 使用ndarray创建DataFrame np.random.seed(10) df = DataFrame(data=np.random.randint(0,100,size=(3,4)),index=['a','b','c'],columns=['A','B','C','D']) df 输出: A B C D a 9 15 64 28 b 89 93 29 8 c 73 0 40 36 # DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。 data = {'k':['a', 'b', 'c'], 'v':[1, 2, 3]} df = pd.DataFrame(data) df 输出: k v 0 a 1 1 y 2 2 z 3
对列进行索引
- 通过类似字典的方式 df['q'] df = DataFrame({'张三':[130,140,150],'李四':[100,110,90]},index=['语文','数学','英语']) df 输出: 张三 李四 语文 130 100 数学 140 110 英语 150 90 # 默认列索引 df['李四'] 输出: 语文 100 数学 110 英语 90 Name: 李四, dtype: int64 # 获取前两列 df[['李四','张三']] 输出: 李四 张三 语文 100 130 数学 110 140 英语 90 150
对行进行索引
- 使用.loc[]加index来进行行索引 - 使用.iloc[]加整数来进行行索引 - 同样返回一个Series,index为原来的columns # 使用显示索引 df.loc['语文'] 输出: 张三 130 李四 100 Name: 语文, dtype: int64 # 使用隐式索引 df.iloc[0] 输出: 张三 130 李四 100 Name: 语文, dtype: int64
对元素索引的方法
- 使用列索引 - 使用行索引(iloc[3,1] or loc['C','q']) - 行索引在前,列索引在后 df['李四']['数学'] 输出: 110 # 注;下面两个反之,报错 df.loc['语文']['李四'] or df.loc['语文','李四'] 输出: 100 df.loc[['语文','英语'],'李四'] 输出: 语文 100 英语 90 Name: 李四, dtype: int64
注意,直接用中括号时:
# 索引 df[列索引]:取一列 df[[col1,col2]]:取出两列 df.loc[显示的行索引]:取行 df.loc[行,列]:取元素 # 切片 df[index1:index3]:切行 df.loc[col1:col3]:切列 df = DataFrame({'张三':[130,140,150],'李四':[100,110,90]},index=['语文','数学','英语']) df 输出: 张三 李四 语文 130 100 数学 140 110 英语 150 90 # 切前两行数据 df[0:2] 输出: 张三 李四 语文 130 100 数学 140 110 # 在loc和iloc中使用切片(切列) df.iloc[:,0:1] 输出: 张三 语文 130 数学 140 英语 150
同Series一样:
df = DataFrame({'张三':[130,140,150],'李四':[100,110,90]},index=['语文','数学','英语']) df 输出: 张三 李四 语文 130 100 数学 140 110 英语 150 90 qizhong = df qimo = df-30 qizhong 输出: 张三 李四 语文 130 100 数学 140 110 英语 150 90 qimo 输出: 张三 李四 语文 100 70 数学 110 80 英语 120 60 # 求两个DataFrame数据平均值 (qizhong + qimo)/2 输出: 张三 李四 语文 115.0 85.0 数学 125.0 95.0 英语 135.0 75.0 # 修改张三qizhong数学成绩为120 qizhong['张三']['数学'] = 120 qizhong.loc['数学','张三'] = 120 qizhong 输出: 张三 李四 语文 130 100 数学 120 110 英语 150 90 qizhong['李四'] -= 50 qizhong 输出: 张三 李四 语文 130 50 数学 120 60 英语 150 40
pd.concat()
pd.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False)
df1 = DataFrame(data=np.random.randint(0,100,size=(3,4))) df2 = DataFrame(data=np.random.randint(0,100,size=(3,3))) df1 输出: 0 1 2 3 a 8 63 94 29.0 b 97 81 37 84.0 c 84 78 76 11.0 df2 输出: 0 1 2 a 83 17 61 d 94 95 3 c 34 46 84 # 外连接:补NaN(默认模式) pd.concat((df1,df2)) 输出: 0 1 2 3 a 8 63 94 29.0 b 97 81 37 84.0 c 84 78 76 11.0 a 83 17 61 NaN d 94 95 3 NaN c 34 46 84 NaN # 内连接:只连接匹配的项 df1 = DataFrame(data=np.random.randint(0,100,size=(3,4)),index=['a','b','c']) df2 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','d','c']) pd.concat((df1,df2),axis=0,join='inner') 输出: 0 1 2 a 8 63 94 b 97 81 37 c 84 78 76 a 83 17 61 d 94 95 3 c 34 46 84
pd.merge()
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True)
# merge与concat的区别在于,merge需要依据某一共同的列来进行合并
# 使用pd.merge()合并时,会自动根据两者相同名称的那一列,作为key来进行合并。
# 注意: 每一列元素的顺序不要求一致
left : 一个DataFrame对象。
right : 另一个DataFrame对象。
on : 列(名)加入上。必须在左右DataFrame对象中都找到。
left_on : 左侧DataFrame中的列用作键。可以是列名,也可以是长度等于DataFrame长度的数组。
right_on : 右侧DataFrame中的列用作键。可以是列名,也可以是长度等于DataFrame长度的数组。
left_index : 如果为True,则使用左侧DataFrame的索引(行标签)作为其连接键。如果DataFrame具有MultiIndex(分层),则级别数必须与右侧DataFrame中的连接键数匹配。
right_index : 相同的使用作为left_index为正确的数据帧。
how : “left”,“right”,“inner”,“内”之一。默认为inner。
合并方法 | SQL等效 | 描述 |
---|---|---|
left | LEFT OUTER JOIN | 使用左侧对象的key |
right | RIGHT OUTER JOIN | 使用正确对象的key |
outer | FULL OUTER JOIN | 使用联合key |
inner | INNER JOIN | 使用key的交集 |
sort : 排序的结果数据框中加入字典顺序按键。默认情况下为True,在许多情况下,设置为False将大大提高性能。
# 一对一匹配合并 df1 = DataFrame({'employee':['Bob','Jake','Lisa'], 'group':['Accounting','Engineering','Engineering'], }) df2 = DataFrame({'employee':['Lisa','Bob','Jake'], 'hire_date':[2004,2008,2012], }) df1 输出: employee group 0 Bob Accounting 1 Jake Engineering 2 Lisa Engineering df2 输出: employee hire_date 0 Lisa 2004 1 Bob 2008 2 Jake 2012 pd.merge(df1,df2) 输出: employee group hire_date 0 Bob Accounting 2008 1 Jake Engineering 2012 2 Lisa Engineering 2004 # 多对一不合并:指左表单行匹配右表多行数据 df3 = DataFrame({ 'employee':['Lisa','Jake'], 'group':['Accounting','Engineering'], 'hire_date':[2004,2016]}) df4 = DataFrame({'group':['Accounting','Engineering','Engineering'], 'supervisor':['Carly','Guido','Steve'] }) df3 输出: employee group hire_date 0 Lisa Accounting 2004 1 Jake Engineering 2016 df4 输出: group supervisor 0 Accounting Carly 1 Engineering Guido 2 Engineering Steve pd.merge(df3,df4) 输出: employee group hire_date supervisor 0 Lisa Accounting 2004 Carly 1 Jake Engineering 2016 Guido 2 Jake Engineering 2016 Steve # 多对多匹配:指左表多行匹配右表多行数据 df1 输出: employee group 0 Bob Accounting 1 Jake Engineering 2 Lisa Engineering df4 输出: group supervisor 0 Accounting Carly 1 Engineering Guido 2 Engineering Steve pd.merge(df1,df4) employee group supervisor 0 Bob Accounting Carly 1 Jake Engineering Guido 2 Jake Engineering Steve 3 Lisa Engineering Guido 4 Lisa Engineering Steve # key的规范化 df1 = DataFrame({'employee':['Jack',"Summer","Steve"], 'group':['Accounting','Finance','Marketing']}) df2 = DataFrame({'employee':['Jack','Bob',"Jake"], 'hire_date':[2003,2009,2012], 'group':['Accounting','sell','ceo']}) df1 输出: employee group 0 Jack Accounting 1 Summer Finance 2 Steve Marketing df2 输出: employee hire_date group 0 Jack 2003 Accounting 1 Bob 2009 sell 2 Jake 2012 ceo # 使用key的交集 pd.merge(df1,df2,how='inner') pd.merge(df1,df2) 输出: employee group hire_date 0 Jack Accounting 2003 # 联合key pd.merge(df1,df2,how='outer') 输出: employee group hire_date 0 Jack Accounting 2003.0 1 Summer Finance NaN 2 Steve Marketing NaN 3 Bob sell 2009.0 4 Jake ceo 2012.0 # 当有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名 pd.merge(df1,df2,on='group',how='outer') 输出: employee_x group employee_y hire_date 0 Jack Accounting Jack 2003.0 1 Summer Finance NaN NaN 2 Steve Marketing NaN NaN 3 NaN sell Bob 2009.0 4 NaN ceo Jake 2012.0 # 当两张表没有可进行连接的列时,可使用left_on和right_on手动指定merge中左右两边的哪一列列作为连接的列 df1 = DataFrame({'employee':['Bobs','Linda','Bill'], 'group':['Accounting','Product','Marketing'], 'hire_date':[1998,2017,2018]}) df2 = DataFrame({'name':['Lisa','Bobs','Bill'], 'hire_dates':[1998,2016,2007]}) df1 输出: employee group hire_date 0 Bobs Accounting 1998 1 Linda Product 2017 2 Bill Marketing 2018 df2 输出: name hire_dates 0 Lisa 1998 1 Bobs 2016 2 Bill 2007 pd.merge(df1,df2,left_on='employee',right_on='name',how='outer') 输出: employee group hire_date name hire_dates 0 Bobs Accounting 1998.0 Bobs 2016.0 1 Linda Product 2017.0 NaN NaN 2 Bill Marketing 2018.0 Bill 2007.0 3 NaN NaN NaN Lisa 1998.0 pd.merge(df1,df2,left_index=True,right_index=True,how='outer') 输出: employee group hire_date name hire_dates 0 Bobs Accounting 1998 Lisa 1998 1 Linda Product 2017 Bobs 2016 2 Bill Marketing 2018 Bill 2007
import tushare as ts
ts.set_token('your token here')
pro = ts.pro_api()
df = ts.get_k_data('600519',start='1900-01-01')
df.to_csv('./maotai.csv')
df = pd.read_csv('./maotai.csv') df.drop(labels='Unnamed: 0',axis=1,inplace=True) #验证data列中数据类型,发现为str type(df['date'][0]) 输出: str # 将date这一列的数据先转成时间类型然后将其作为原数据的行索引 df = pd.read_csv('./maotai.csv',index_col='date',parse_dates=['date']) df.drop(labels='Unnamed: 0',axis=1,inplace=True) df - labels:一个字符或者数值,加上axis ,表示带label标识的行或者列;如 (labels='A', axis=1) 表示A列 - axis:axis=0表示行,axis=1表示列 - columns:列名 - index:表示dataframe的index, 如index=1, index=a - inplace:True表示删除某行后原dataframe变化,False不改变原始dataframe # 输出该股票所有收盘比开盘上涨3%以上的日期 #(收盘-开盘)/开盘 > 0.03 (df['close'] - df['open']) / df['open'] > 0.03 #True:满足需求 #false:不满足 #返回了满足需求的行数据 df.loc[(df['close'] - df['open']) / df['open'] > 0.03] #获取了满足需求的日期 df.loc[(df['close'] - df['open']) / df['open'] > 0.03].index #结论:如果获取了一组布尔值,接下来改组布尔值就直接作为元数据的行索引
(df['open'] - df['close'].shift(1))/df['close'].shift(1) < -0.02
# shift(1) 是将索引列下移一行
# 满足需求的行数据
df.loc[(df['open'] - df['close'].shift(1))/df['close'].shift(1) < -0.02].index
# 数据的重新取样的机制(resample):根据指定好的规则进行指定数据的提取 # 根据月份提取 df_monthly = df_new.resample('M').first() df_monthly.head() # 计算出买股票一共花了多少钱 cost_money = df_monthly['open'].sum()*100 cost_money 输出: 3679128.6999999997 # 计算卖出所有的股票一共进账多少钱 # 根据年份提取 df_yearly = df_new.resample('A').last() # 去除最后一年 df_yearly = df_yearly[:-1] recv_money = df_yearly['open'].sum()*1200 recv_money 输出: 3160378.8000000003 # 19年买入了900只股票没有卖出,剩余的股票也计算到总收益 # 剩余股票的单价应该选择使用昨日的收盘价 # 最后一行 last_price = df.iloc[-1]['close'] last_price cunHuo_price = last_price['close'] * 900 # 计算总收益 cunHuo_price+recv_money-cost_money 输出: 515260.100000001
有两种丢失数据:
None
None
是Python自带的,其类型为python object
。因此,None
不能参与到任何计算中。
#查看None的数据类型
type(None)
输出:
NoneType
NaN
np.nan
是浮点类型,能参与到计算中。但计算的结果总是NaN
。
type(np.nan) 输出: float # 将某些元素设置为NaN from pandas import DataFrame import numpy as np df = DataFrame(data=np.random.randint(0,100,size=(3,4))) print(df) df.iloc[0,0]=None df.iloc[1,1]=np.nan df.iloc[2,2]=None df 输出: 0 1 2 3 0 83 7 94 91 1 21 42 84 27 2 55 60 48 92 0 1 2 3 0 NaN 93.0 31.0 47 1 50.0 NaN 38.0 7 2 40.0 89.0 NaN 94
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
# 示例
df.dropna(axis=0,how='any',inplace=False)
# 移除指定列(col01)有空值的行
df.dropna(axis=0,subset=['col01'] ,how='any',inplace=False)
# Pandas 把 n/a 和 NA 当作空数据,na 不是空数据,不符合我们要求,我们可以指定空数据类型:
missing_values = ["n/a", "na", "--"]
df = pd.read_csv('property-data.csv', na_values = missing_values)
# 判断列中是否存在空值,axis=1时判断行
df.isnull().any(axis=0)
any() :一行(或一列)里任何一个数据有出现 NA 就去掉整行
all(): 一行(或列)都是 NA 才去掉这整行。
fillna()
方法来替换空字段# 使用12345数据替换空字段
df.fillna(12345, inplace = True)
# 指定某列替换空字段,如使用 12345 替换 PID 为空数据:
df['PID'].fillna(12345, inplace = True)
#
# 数据清洗:填充空值
df.fillna(method='ffill',axis=0,inplace=True)
df.fillna(method='bfill',axis=0,inplace=True)
# method:指定一个值去替换缺失值(缺省默认这种方式)
# 'ffill':用前一个非缺失值去填充该缺失值
# 'bfill':用后一个非缺失值去填充该缺失值
# axis:默认为0,表示行填充,axis=1表示列填充。
# 如果对应的数据是重复的,duplicated() 会返回 True,否则返回 False。
df.duplicated()
# 删除重复数据
df.drop_duplicates(subset = None,keep = 'first',inplace = False,ignore_index = False,)
keep : {'first', 'last', False}
df = pd.DataFrame(np.random.random(size=(100,3)),columns=['A','B','C'])
std_twice = df['C'].std()*2
std_twice_index = df.loc[df['C']>std_twice].index
df.drop(labels=std_twice_index,axis=0,inplace=True)
df.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad',)
# 单值替换
普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
按列指定单值替换: to_replace={列标签:替换值} value='value'
# 多值替换
列表替换: to_replace=[] value=[]
字典替换(推荐) to_replace={to_replace:value,to_replace:value}
df = pd.DataFrame(data=np.random.randint(1,100,size=(8,5))) df 输出: 0 1 2 3 0 91 22 61 58 1 80 52 86 10 2 57 85 21 90 # 替换单值 df.replace(to_replace=10,value='ten',inplace=True) df.replace(to_replace=80,value='ten',inplace=True) 输出: 0 1 2 3 0 91 22 61 58 1 ten 52 86 ten 2 57 85 21 90 # 只替换第一列的数据 df.replace(to_replace={0:'ten'},value='one0') 输出: 0 1 2 3 0 91 22 61 58 1 one0 52 86 ten 2 57 85 21 90 # 替换多值:列表 df.replace(to_replace=['ten',91],value=['one0','nineOne']) 输出: 0 1 2 3 0 nineOne 22 61 58 1 10 52 86 10 2 57 85 21 90 # 替换多值:字典 df.replace(to_replace={'ten':'One0',91:'nine1'}) 输出: 0 1 2 3 0 nine1 22 61 58 1 One0 52 86 One0 2 57 85 21 90
map()
# 创建数据表 dic = { 'name':['张三','李四','王五'], 'Score':[130,140,150], } df = pd.DataFrame(data=dic) df 输出: name Score 0 张三 130 1 李四 140 2 王五 150 # 映射关系表 dic = { '张三':'san', '李四':'si', '王五':'wu' } df['nick_name'] = df['name'].map(dic) df name Score nick_name 0 张三 130 san 1 李四 140 si 2 王五 150 wu # 将map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的,(参数:lambda,函数) def true_score(s): return s*0.75 df['true_score'] = df['Score'].map(true_score) df 输出: name Score nick_name true_score 0 张三 130 san 97.5 1 李四 140 si 105.0 2 王五 150 wu 112.5
df['Score'].apply(true_score)
输出:
0 97.5
1 105.0
2 112.5
Name: Score, dtype: float64
take()函数接受一个索引列表,用数字表示,使得df根据列表中索引的顺序进行采样
# 行采样 df.take([1,0,2]) 输出: A B C 1 0.021581 0.400854 0.986081 0 0.158678 0.888694 0.498163 2 0.974851 0.925864 0.147149 # 列采样 df.take([1,0,2],axis=1).head(2) 输出: B A C 0 0.888694 0.158678 0.498163 1 0.400854 0.021581 0.986081 # 随机抽样 # 随机列展示,再随机抽样10个数据 df.take(np.random.permutation(3),axis=1).take(np.random.permutation(10),axis=0)
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'], 'price':[4,3,3,2.5,4,2], 'color':['red','yellow','yellow','green','green','green'], 'weight':[12,20,50,30,20,44]}) df 输出: item price color weight 0 Apple 4.0 red 12 1 Banana 3.0 yellow 20 2 Orange 3.0 yellow 50 3 Banana 2.5 green 30 4 Orange 4.0 green 20 5 Apple 2.0 green 44 # 使用groupby实现分组 # 使用groups查看分组情况 df.groupby('item',axis=0) df.groupby('item',axis=0).groups 输出: {'Apple': [0, 5], 'Banana': [1, 3], 'Orange': [2, 4]}
分组后的成员中可以被进行运算的值会进行运算,不能被运算的值不进行运算
# 默认如果不指定列的话,会计算所有列的平均值,此处指定计算price列 # 以item中的项目分组计算每个项目价格的平均值 s = df.groupby('item').mean()['price'] s.to_dict() df['mean_price'] = df['item'].map(s.to_dict()) 输出: item price color weight mean_price 0 Apple 4.0 red 12 3.00 1 Banana 3.0 yellow 20 2.75 2 Orange 3.0 yellow 50 3.50 3 Banana 2.5 green 30 2.75 4 Orange 4.0 green 20 3.50 5 Apple 2.0 green 44 3.00 # 以color中的项目分组计算每个颜色价格的平均值 s = df.groupby('color',axis=0).mean()['price'].to_dict() df['color_mean_price'] = df['color'].map(s) item price color weight mean_price color_mean_price 0 Apple 4.0 red 12 3.00 4.000000 1 Banana 3.0 yellow 20 2.75 3.000000 2 Orange 3.0 yellow 50 3.50 3.000000 3 Banana 2.5 green 30 2.75 2.833333 4 Orange 4.0 green 20 3.50 2.833333 5 Apple 2.0 green 44 3.00 2.833333
df.groupby('item')['price'].sum() 近似于 df.groupby('item')['price'].apply(sum) 输出: item Apple 6.0 Banana 5.5 Orange 7.0 Name: price, dtype: float64 # 自定义处理函数 def myFun(s):# 必须要有一个参数 sum = 0 for i in s: sum +=i return sum/len(s) df.groupby(by='item')['price'].apply(myFun) 输出: 0 3.00 1 2.75 2 3.50 3 2.75 4 3.50 5 3.00 Name: price, dtype: float64 df.groupby(by='item')['price'].transform(myFun) 输出: 0 3.00 1 2.75 2 3.50 3 2.75 4 3.50 5 3.00 Name: price, dtype: float64
months = {'JAN' : 1, 'FEB' : 2, 'MAR' : 3, 'APR' : 4, 'MAY' : 5, 'JUN' : 6, 'JUL' : 7, 'AUG' : 8, 'SEP' : 9, 'OCT': 10, 'NOV': 11, 'DEC' : 12} of_interest = ['Obama, Barack', 'Romney, Mitt', 'Santorum, Rick', 'Paul, Ron', 'Gingrich, Newt'] parties = { 'Bachmann, Michelle': 'Republican', 'Romney, Mitt': 'Republican', 'Obama, Barack': 'Democrat', "Roemer, Charles E. 'Buddy' III": 'Reform', 'Pawlenty, Timothy': 'Republican', 'Johnson, Gary Earl': 'Libertarian', 'Paul, Ron': 'Republican', 'Santorum, Rick': 'Republican', 'Cain, Herman': 'Republican', 'Gingrich, Newt': 'Republican', 'McCotter, Thaddeus G': 'Republican', 'Huntsman, Jon': 'Republican', 'Perry, Rick': 'Republican' } #读取数据 df = pd.read_csv('./usa_election.txt') df.head(2) 输出: cmte_id cand_id cand_nm contbr_nm contbr_city \ 0 C00410118 P20002978 Bachmann, Michelle HARVEY, WILLIAM MOBILE 1 C00410118 P20002978 Bachmann, Michelle HARVEY, WILLIAM MOBILE contbr_st contbr_zip contbr_employer contbr_occupation contb_receipt_amt \ 0 AL 366010290.0 RETIRED RETIRED 250.0 1 AL 366010290.0 RETIRED RETIRED 50.0 contb_receipt_dt receipt_desc memo_cd memo_text form_tp file_num 0 20-JUN-11 NaN NaN NaN SA17A 736166 1 23-JUN-11 NaN NaN NaN SA17A 736166 #新建一列各个候选人所在党派party df['party'] = df['cand_nm'].map(parties) df.head(2) #查看colums:party这一列中有哪些元素 df['party'].unique() #统计party列中各个元素出现次数 df['party'].value_counts() #查看各个党派收到的政治献金总数 df.groupby('party')['contb_receipt_amt'].sum() #每天每个党派收到政治现金的总数 df.groupby(['contb_receipt_dt','party'])['contb_receipt_amt'].sum() # 将表中日期格式转换为'yyyy-mm-dd' def new_date(s): day,month,year=s.split('-') month=months[month] return '20'+year+'-'+str(month)+'-'+day df['contb_receipt_dt']=df['contb_receipt_dt'].map(new_date) df.head(2) # 查看老兵(捐献者职业)DISABLED VETERAN主要支持谁(给谁捐钱最多) df['contbr_occupation'] == 'DISABLED VETERAN' disabled_veteran = df.loc[df['contbr_occupation'] == 'DISABLED VETERAN'] disabled_veteran.groupby('cand_nm')['contb_receipt_amt'].sum() #候选人的捐赠者中,捐赠金额最大的人的职业以及捐献额 df['contb_receipt_amt'].max() df.query('contb_receipt_amt == 1944042.43')[['contbr_occupation','contb_receipt_amt']]
import numpy as np import pandas as pd import matplotlib.pyplot as plt from pylab import mpl from sklearn.linear_model import LinearRegression mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体 mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题 # 整合数据 ferrara1 = pd.read_csv('./ferrara_150715.csv') ferrara2 = pd.read_csv('./ferrara_250715.csv') ferrara3 = pd.read_csv('./ferrara_270615.csv') ferrara=pd.concat([ferrara1,ferrara1,ferrara1],ignore_index=True) ... faenza3 = pd.read_csv('./faenza_270615.csv') faenza = pd.concat([faenza1,faenza2,faenza3],ignore_index=True) # 去除无用的列 city_list = [ferrara,torino,mantova,milano,ravenna,asti,bologna,piacenza,cesena,faenza] for city in city_list: city.drop(labels='Unnamed: 0',axis=1,inplace=True) # 显示最高温度于离海远近的关系 max_temp=[] city_dist = [] for city in city_list: temp = city['temp'].max() max_temp.append(temp) dist = city['dist'].max() city_dist.append(dist) city_dist # 绘制散点图 plt.scatter(city_dist,max_temp) plt.xlabel('距离') plt.ylabel('温度') plt.title('城市最高温度和离海远近之间的关系') #对当前的数据建立一个算法模型,然后可以让模型实现预测的功能(根据距离预测最高温度)。 # y = kx + b线性方程,该方程还没有求出解 # 如果方程中的k和b是已知的,则该方程就有解 # 建立线性回归算法模型对象 linner = LinearRegression() #样本数据的封装/提取 feature = np.array(city_dist) feature = feature.reshape(-1, 1) target = np.array(max_temp) #对模型进行训练 linner.fit(feature,target) #X:二维形式的特征数据,y:目标数据 # (标量) 系数b linner.intercept_ # (数组)斜率 linner.coef_ # 对预测结果计算出的决定系数R^2 # 决定系数反应了y的波动有多少百分比能被x的波动所描述,即表征依变数Y的变异中有多少百分比,可由控制的自变数X来解释。 # 意义:拟合优度越大,说明x对y的解释程度越高。自变量对因变量的解释程度越高,自变量引起的变动占总变动的百分比高。观察点在回归直线附近越密集。 linner.score(feature,target) # 绘制回归曲线 x = np.linspace(0,350,100).reshape(-1,1) y = linner.predict(x) plt.scatter(city_dist,max_temp) plt.scatter(x,y) plt.xlabel('距离') plt.ylabel('温度') plt.title('海滨城市最高温度和离海远近之间的关系')
score的实现原理:
print('模型预测的温度:',linner.predict(feature))
print('真实温度:',target)
KNN算法原理:
工作原理:
实例:KNN手写数字识别
#特征数据的职位是字符串类型的数据,特征数据在knn中是需要参与运算,必须将字符串类型的特征数据转换为数值型的数据 import numpy as np import matplotlib .pyplot as plt from sklearn.neighbors import KNeighborsClassifier # 样本数据的提取 feature = [] target = [] for i in range(7):#i:0-9表示的是文件夹的名称 for j in range(1,501):#j:1-500表示的是图片的名称的一部分 imgPath = './data/'+str(i)+'/'+str(i)+'_'+str(j)+'.bmp' img_arr = plt.imread(imgPath) feature.append(img_arr) target.append(i) target = np.array(target) # feature目前是三维的numpy数组。必须变形成二维的才可以作为特征数据 feature = np.array(feature) feature.shape # 变形成二维 feature = feature.reshape(5000,784) # 进行样本数据的打乱 np.random.seed(10) np.random.shuffle(feature) np.random.seed(10) np.random.shuffle(target) # 对样本数据进行拆分 # 测试数据 # 训练数据 #训练数据是以train结尾的 x_train = feature[:4950] y_train = target[:4950] #测试数据是以test结尾的 x_test = feature[4950:] y_test = target[4950:] knn = KNeighborsClassifier(n_neighbors=9) knn.fit(x_train,y_train) knn.score(x_test,y_test) #对模型进行测试 print('真实的结果:',y_test) print('模型分类的结果:',knn.predict(x_test)) # 保存训练好的模型 from sklearn.externals import joblib #保存 joblib.dump(knn,'./knn.m') #读取 knn = joblib.load('./knn.m') knn # 将外部图片带入模型进行分类的测试 img_arr = plt.imread('./数字.jpg') plt.imshow(img_arr) # 切对应的数据 eight_arr = img_arr[175:240,85:135] plt.imshow(eight_arr) # 模型只可以测试类似于测试数据中的特征数据 x_test[4].shape # 将8对应的图片进行降维(65, 50, 3)降低成(784,) # 将图片降低为2维 eight_arr = eight_arr.mean(axis=2) #进行图片像素的等比例压缩 import scipy.ndimage as ndimage eight_arr = ndimage.zoom(eight_arr,zoom=(28/65,28/50)) eight_arr = eight_arr.reshape(1,784) # 分类数据 knn.predict(eight_arr)
本文转自 https://www.cnblogs.com/f-carey/p/17216794.html,如有侵权,请联系删除。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。