数据处理(numpy & pandas & scipy & matplotlib.pyplot)

数据处理(numpy & pandas & scipy & matplotlib.pyplot)

numpy

参考网址:
https://www.jianshu.com/p/57e3c0a92f3a
啥都解释了:https://zhuanlan.zhihu.com/p/20878530

小知识点

  • 迭代对象与迭代器:https://blog.csdn.net/jinixin/article/details/72232604
    my_list_iter = iter(my_list) # 得到该对象的迭代器实例,iter函数在下面会详细解释(iter获取迭代器。。。)
  • 生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和 next方法),不需要再手动实现两方法。
  • 生成器在迭代的过程中可以改变当前迭代值,而修改普通迭代器的当前迭代值往往会发生异常,影响程序的执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#数学之美
import numpy as np
import matplotlib.pyplot as plt

def mandelbrot(h, w, maxit=20):
y, x = np.ogrid[-1.4:1.4:h * 1j, -2:0.8:w * 1j]
c = x + y * 1j
z = c
divtime = maxit + np.zeros(z.shape, dtype=int)
for i in range(maxit):
z = z ** 2 + c
diverge = z * np.conj(z) > 2 ** 2 # who is diverging
div_now = diverge & (divtime == maxit) # who is diverging now
divtime[div_now] = i # note when
z[diverge] = 2 # avoid diverging too much
return divtime

plt.imshow(mandelbrot(400, 400))
plt.show()

柱形图 hist

1
2
3
4
5
6
7
8
9
import numpy as np
import matplotlib.pyplot as plt

# Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
mu, sigma = 2, 0.5
v = np.random.normal(mu, sigma, 10000)
# Plot a normalized histogram with 50 bins
plt.hist(v, bins=50, normed=1) # matplotlib version (plot)
plt.show()

柱形图的顶点线型图

1
2
3
4
5
6
7
8
9
10
import numpy as np
import matplotlib.pyplot as plt

# Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
mu, sigma = 2, 0.5
v = np.random.normal(mu, sigma, 10000)
# Compute the histogram with numpy and then plot it
(n, bins) = np.histogram(v, bins=50, normed=True) # NumPy version (no plot)
plt.plot(.5 * (bins[1:] + bins[:-1]), n)
plt.show()

合并:https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/2-6-np-concat/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
df2 = pd.DataFrame({'A' : 1.,
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo'})

print(df2)

"""
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
"""

数据清洗

知乎专栏:https://zhuanlan.zhihu.com/dataclean

参考网址:https://zhuanlan.zhihu.com/p/20571505

pandas 小知识点学习参考

https://blog.csdn.net/tanzuozhev/column/info/16726

  • 数据表中的重复值duplicated() & drop_duplicates()
  • 数据表中的空值 isnull() & notnull() & fillna(0)–>填充nan为0 & dropna()
  • 数据间的空格
1
2
3
loandata['term']=loandata['term'].map(str.strip)
loandata['term']=loandata['term'].map(str.lstrip)
loandata['term']=loandata['term'].map(str.rstrip)
  • 大小写转换:
1
2
3
loandata['term']=loandata['term'].map(str.upper)
loandata['term']=loandata['term'].map(str.lower)
loandata['term']=loandata['term'].map(str.title)

数据清洗

Pandas透视表(pivot_table)详解

https://blog.csdn.net/liuweiyuxiang/article/details/78183896

inplace=True–>表示在原数据或者结构上进行操作修改

pandas的factorize()理解

factorize函数可以将Series中的标称型数据映射称为一组数字,相同的标称型映射为相同的数字。factorize函数的返回值是一个tuple(元组),元组中包含两个元素。第一个元素是一个array,其中的元素是标称型元素映射为的数字;第二个元素是Index类型,其中的元素是所有标称型元素,没有重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import numpy as np
import pandas as pd
In [43]: df = pd.DataFrame({"id":[1,2,3,4,5,6,3,2], "raw_grade":['a', 'b', 'b',
...: 'a', 'a', 'e','c','a']})

In [44]: df
Out[44]:
id raw_grade
0 1 a
1 2 b
2 3 b
3 4 a
4 5 a
5 6 e
6 3 c
7 2 a

In [45]: x = pd.factorize(df.raw_grade)

In [46]: x
Out[46]:
(array([0, 1, 1, 0, 0, 2, 3, 0], dtype=int64),
Index(['a', 'b', 'e', 'c'], dtype='object'))
#array中的元素其实是df.raw_grade的对应位置元素在Index中的下标。例如array第一个元素是0,表示df.raw_grade的第一个元素为Index的第0个元素。

In [47]: x[1]
Out[47]: Index(['a', 'b', 'e', 'c'], dtype='object')

In [48]: x[0]
Out[48]: array([0, 1, 1, 0, 0, 2, 3, 0], dtype=int64)

In [49]: type(x)
Out[49]: tuple

pandas 修改DataFrame列名

参考链接:https://blog.csdn.net/liuweiyuxiang/article/details/78445440

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>>a.rename(columns={'A':'a', 'B':'b', 'C':'c'}, inplace = True)
>>>a
a b c
0 1 4 7
1 2 5 8
2 3 6 9

>>>a.rename(columns={'A':'a', 'C':'c'}, inplace = True) # inplace的意思是在原DataFrame上完成
>>>a
a B c
0 1 4 7
1 2 5 8
2 3 6 9
# 可以只修改A,C两列的名称,而不修改B。

pandas 值的替换

1
2
3
4
5
6
7
8
9
10
replace_map={
-999:None
}
obj.replace(replace_map)
||
frame.rename(
index={'Ohio':'Indiana'},
columns={'three':'peekaboo'},
inplace=True
)

数据重排与随机采样

根据给定的索引对行进行重排,选取数据等。

1
2
3
4
5
6
frame=pd.DataFrame(np.arange(20).reshape((5,4)))
re_order=np.random.permutation(frame.shape[0])

training_set=frame.iloc[re_order[:3],:]
test_set=frame.iloc[re_order[3:],:]
mini_batch=training_set.sample(1,replace=True)

非 ASCII 字符

1
2
3
# 删除非 ASCII 字符
df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)

pandas中关于axis的理解

参考链接:https://blog.csdn.net/liuweiyuxiang/article/details/80895844

例如一个shape(3,2,4)的数组,代表一个三维数组,要注意的是这里的维度与物理学的维度的理解是不太一样的
axis = 0时,就相当于所求的数组的结果变成shape(2,4)
axis = 1时,数组的结果shape(3,4)
axis = 2时,数组的结果shape(3,2)
这里应该看出来了,当axis=n的时候shape中相应的索引就会被去除,数组发生了降维,那么是如何降维的呢?首先要清楚shape里的数字都代表什么意义:
3代表这个numpy数组里嵌套着3个数组(有三层), 2代表其中每个数组的行数,3代表其中每个数组的列数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>>df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], \
columns=["col1", "col2", "col3", "col4"])
>>>df
col1 col2 col3 col4
0 1 1 1 1
1 2 2 2 2
2 3 3 3 3
# 如果我们调用df.mean(axis=1),我们将得到按行计算的均值
>>> df.mean(axis=1)
0 1
1 2
2 3
然而,如果我们调用 df.drop((name, axis=1),我们实际上删掉了一列,而不是一行:
>>> df.drop("col4", axis=1)
col1 col2 col3
0 1 1 1
1 2 2 2
2 3 3 3

其实问题理解axis有问题,df.mean其实是在每一行上取所有列的均值,而不是保留每一列的均值。也许简单的来记就是axis=0代表往跨行(down),而axis=1代表跨列(across),作为方法动作的副词(译者注)

换句话说:

  • 使用0值表示沿着每一列或行标签\索引值向下执行方法
  • 使用1值表示沿着每一行或者列标签模向执行对应的方法

下图代表在DataFrame当中axis为0和1时分别代表的含义:

axis参数作用方向图示。另外,记住,Pandas保持了Numpy对关键字axis的用法,用法在Numpy库的词汇表当中有过解释:轴用来为超过一维的数组定义的属性,二维数据拥有两个轴:第0轴沿着行的垂直往下,第1轴沿着列的方向水平延伸。
所以问题当中第一个列子 df.mean(axis=1)代表沿着列水平方向计算均值,而第二个列子df.drop(name, axis=1) 代表将name对应的列标签(们)沿着水平的方向依次删掉。即df.mean(axis=1)表示一行一行的计算均值,df.drop(name, axis=1)表示一行一行的将name列删掉。还可以这样理解,axis等于那个维度代表操作在哪个维度上进行,操作后该维度消失(变成1)。如df.mean(axis=1),axis=1表示均值操作在列上进行(跨列操作),即按照行相加求均值,操作后变成一列。axis指定哪个维度表示跨哪个维度进行操作。

scikit-learn中评估分类器性能的度量,像混淆矩阵、ROC、AUC等

参考链接:https://blog.csdn.net/liuweiyuxiang/article/details/78475419

数据处理常用函数大全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import numpy as np  
import pandas as pd
import matplotlib.pyplot as plt
from pandas import read_csv;
from pandas import to_datetime;


---------------numpy-----------------------
arr = np.array([1,2,3], dtype=np.float64)
np.zeros((3,6)) np.empty((2,3,2)) np.arange(15)
arr.dtype arr.ndim arr.shape
arr.astype(np.int32) #np.float64 np.string_ np.unicode_
arr * arr arr - arr 1/arr
arr= np.arange(32).reshape((8,4))
arr[1:3, : ] #正常切片
arr[[1,2,3]] #花式索引
arr.T arr.transpose((...)) arr.swapaxes(...) #转置
arr.dot #矩阵内积
np.sqrt(arr) np.exp(arr) randn(8)#正态分布值 np.maximum(x,y)
np.where(cond, xarr, yarr) #当cond为真,取xarr,否则取yarr
arr.mean() arr.mean(axis=1) #算术平均数
arr.sum() arr.std() arr.var() #和、标准差、方差
arr.min() arr.max() #最小值、最大值
arr.argmin() arr.argmax() #最小索引、最大索引
arr.cumsum() arr.cumprod() #所有元素的累计和、累计积
arr.all() arr.any() # 检查数组中是否全为真、部分为真
arr.sort() arr.sort(1) #排序、1轴向上排序
arr.unique() #去重
np.in1d(arr1, arr2) #arr1的值是否在arr2中
np.load() np.loadtxt() np.save() np.savez() #读取、保存文件
np.concatenate([arr, arr], axis=1) #连接两个arr,按行的方向


---------------pandas-----------------------
ser = Series() ser = Series([...], index=[...]) #一维数组, 字典可以直接转化为series
ser.values ser.index ser.reindex([...], fill_value=0) #数组的值、数组的索引、重新定义索引
ser.isnull() pd.isnull(ser) pd.notnull(ser) #检测缺失数据
ser.name= ser.index.name= #ser本身的名字、ser索引的名字
ser.drop('x') #丢弃索引x对应的值
ser +ser #算术运算
ser.sort_index() ser.order() #按索引排序、按值排序
df = DataFrame(data, columns=[...], index=[...]) #表结构的数据结构,既有行索引又有列索引
df.ix['x'] #索引为x的值 对于series,直接使用ser['x']
del df['ly'] #用del删除第ly列
df.T #转置
df.index.name df.columns.name df.values
df.drop([...])
df + df df1.add(df2, fill_vaule=0) #算术运算
df -ser #df与ser的算术运算
f=lambda x: x.max()-x.min() df.apply(f)
df.sort_index(axis=1, ascending=False) #按行索引排序
df.sort_index(by=['a','b']) #按a、b列索引排序
ser.rank() df.rank(axis=1) #排序,增设一个排名值
df.sum() df.sum(axis=1) #按列、按行求和
df.mean(axis=1, skipna=False) #求各行的平均值,考虑na的存在
df.idxmax() #返回最大值的索引
df.cumsum() #累计求和
df.describe() ser.describe() #返回count mean std min max等值
ser.unique() #去重
ser.value_counts() df.value_counts() #返回一个series,其索引为唯一值,值为频率
ser.isin(['x', 'y']) #判断ser的值是否为x,y,得到布尔值
ser.dropna() ser.isnull() ser.notnull() ser.fillna(0) #处理缺失数据,df相同
df.unstack() #行列索引和值互换 df.unstack().stack()
df.swaplevel('key1','key2') #接受两个级别编号或名称,并互换
df.sortlevel(1) #根据级别1进行排序,df的行、列索引可以有两级
df.set_index(['c','d'], drop=False) #将c、d两列转换为行,因drop为false,在列中仍保留c,d
read_csv read_table read_fwf #读取文件分隔符为逗号、分隔符为制表符('\t')、无分隔符(固定列宽)
pd.read_csv('...', nrows=5) #读取文件前5行
pd.read_csv('...', chunksize=1000) #按块读取,避免过大的文件占用内存
pd.load() #pd也有load方法,用来读取二进制文件
pd.ExcelFile('...xls').parse('Sheet1') # 读取excel文件中的sheet1
df.to_csv('...csv', sep='|', index=False, header=False) #将数据写入csv文件,以|为分隔符,默认以,为分隔符, 禁用列、行的标签
pd.merge(df1, df2, on='key', suffixes=('_left', '_right')) #合并两个数据集,类似数据库的inner join, 以二者共有的key列作为键,suffixes将两个key分别命名为key_left、key_right
pd.merge(df1, df2, left_on='lkey', right_on='rkey') #合并,类似数据库的inner join, 但二者没有同样的列名,分别指出,作为合并的参照
pd.merge(df1, df2, how='outer') #合并,但是是outer join;how='left'是笛卡尔积,how='inner'是...;还可以对多个键进行合并
df1.join(df2, on='key', how='outer') #也是合并
pd.concat([ser1, ser2, ser3], axis=1) #连接三个序列,按行的方向
ser1.combine_first(ser2) df1.combine_first(df2) #把2合并到1上,并对齐
df.stack() df.unstack() #列旋转为行、行旋转为列
df.pivot()
df.duplicated() df.drop_duplicates() #判断是否为重复数据、删除重复数据
df[''].map(lambda x: abs(x)) #将函数映射到df的指定列
ser.replace(-999, np.nan) #将-999全部替换为nan
df.rename(index={}, columns={}, inplace=True) #修改索引,inplace为真表示就地修改数据集
pd.cut(ser, bins) #根据面元bin判断ser的各个数据属于哪一个区段,有labels、levels属性
df[(np.abs(df)>3).any(1)] #输出含有“超过3或-3的值”的行
permutation take #用来进行随机重排序
pd.get_dummies(df['key'], prefix='key') #给df的所有列索引加前缀key
df[...].str.contains() df[...].str.findall(pattern, flags=re.IGNORECASE) df[...].str.match(pattern, flags=...) df[...].str.get() #矢量化的字符串函数

----绘图
ser.plot() df.plot() #pandas的绘图工具,有参数label, ax, style, alpha, kind, logy, use_index, rot, xticks, xlim, grid等,详见page257
kind='kde' #密度图
kind='bar' kind='barh' #垂直柱状图、水平柱状图,stacked=True为堆积图
ser.hist(bins=50) #直方图
plt.scatter(x,y) #绘制x,y组成的散点图
pd.scatter_matrix(df, diagonal='kde', color='k', alpha='0.3') #将df各列分别组合绘制散点图

----聚合分组
groupby() 默认在axis=0轴上分组,也可以在1组上分组;可以用for进行分组迭代
df.groupby(df['key1']) #根据key1对df进行分组
df['key2'].groupby(df['key1']) #根据key1对key2列进行分组
df['key3'].groupby(df['key1'], df['key2']) #先根据key1、再根据key2对key3列进行分组
df['key2'].groupby(df['key1']).size() #size()返回一个含有分组大小的series
df.groupby(df['key1'])['data1'] 等价于 df['data1'].groupby(df['key1'])
df.groupby(df['key1'])[['data1']] 等价于 df[['data1']].groupby(df['key1'])
df.groupby(mapping, axis=1) ser(mapping) #定义mapping字典,根据字典的分组来进行分组
df.groupby(len) #通过函数来进行分组,如根据len函数
df.groupby(level='...', axis=1) #根据索引级别来分组
df.groupby([], as_index=False) #禁用索引,返回无索引形式的数据
df.groupby(...).agg(['mean', 'std']) #一次使用多个聚合函数时,用agg方法
df.groupby(...).transform(np.mean) #transform()可以将其内的函数用于各个分组
df.groupby().apply() #apply方法会将待处理的对象拆分成多个片段,然后对各片段调用传入的函数,最后尝试将各片段组合到一起

----透视交叉
df.pivot_table(['',''], rows=['',''], cols='', margins=True) #margins为真时会加一列all
pd.crosstab(df.col1, df.col2, margins=True) #margins作用同上


---------------matplotlib---------------
fig=plt.figure() #图像所在的基对象
ax=fig.add_subplot(2,2,1) #2*2的图像,当前选中第1个
fig, axes = plt.subplots(nrows, nclos, sharex, sharey) #创建图像,指定行、列、共享x轴刻度、共享y轴刻度
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
#调整subplot之间的距离,wspace、hspace用来控制宽度、高度百分比
ax.plot(x, y, linestyle='--', color='g') #依据x,y坐标画图,设置线型、颜色
ax.set_xticks([...]) ax.set_xticklabels([...]) #设置x轴刻度
ax.set_xlabel('...') #设置x轴名称
ax.set_title('....') #设置图名
ax.legend(loc='best') #设置图例, loc指定将图例放在合适的位置
ax.text(x,y, 'hello', family='monospace', fontsize=10) #将注释hello放在x,y处,字体大小为10
ax.add_patch() #在图中添加块
plt.savefig('...png', dpi=400, bbox_inches='tight') #保存图片,dpi为分辨率,bbox=tight表示将裁减空白部分




------------------------------------------
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
#可以用来绘制地图


-----------------时间序列--------------------------
pd.to_datetime(datestrs) #将字符串型日期解析为日期格式
pd.date_range('1/1/2000', periods=1000) #生成时间序列
ts.resample('D', how='mean') #采样,将时间序列转换成以每天为固定频率的, 并计算均值;how='ohlc'是股票四个指数;
#重采样会聚合,即将短频率(日)变成长频率(月),对应的值叠加;
#升采样会插值,即将长频率变为短频率,中间产生新值
ts.shift(2, freq='D') ts.shift(-2, freq='D') #后移、前移2天
now+Day() now+MonthEnd()
import pytz pytz.timezone('US/Eastern') #时区操作,需要安装pytz
pd.Period('2010', freq='A-DEC') #period表示时间区间,叫做时期
pd.PeriodIndex #时期索引
ts.to_period('M') #时间转换为时期
pd.rolling_mean(...) pd.rolling_std(...) #移动窗口函数-平均值、标准差
df = read_csv('D:\\PA\\4.18\\data.csv', encoding='utf8')
df_dt = to_datetime(df.注册时间, format='%Y/%m/%d');
df_dt.dt.year
df_dt.dt.second;
df_dt.dt.minute;
df_dt.dt.hour;
df_dt.dt.day;
df_dt.dt.month;
df_dt.dt.weekday;

处理丢失数据

1
2
3
4
5
6
7
df.dropna(
axis=0, # 0: 对行进行操作; 1: 对列进行操作
how='any' # 'any': 只要存在 NaNdrop 掉; 'all': 必须全部是 NaNdrop
)
df.fillna(value=0)
df.isnull() # 得到的是布尔型的矩阵
np.any(df.isnull()) == True # 判断是否存在Nan

导入导出数据

1
2
3
4
5
6
7
8
import pandas as pd #加载模块

#读取csv
data = pd.read_csv('student.csv')

#打印出data
print(data)
data.to_pickle('student.pickle') # 将资料存取成pickle