1. 除去字符串中,不需要的字符,只要有用的字符,如
string_list = '[1.0,2.0,0.,3.0]\n' # 只想保留数字
解决方案:使用string模块中的maketrans()和translate()函数
import string
allchars = string.maketrans('', '') # maketrans函数生成一个翻译表(这里默认)
string_list = '[1. 0. 1. 0. 1. 1.]\n'.translate(allchars, '[]\n') # 过滤掉第二个参数中的字符
list_str = string_list.split(" ") # 将字符串分割(split)为字符串列表类型
list_float = map(float, list_str) # 将列表中元素,由字符串类型转换为浮点数
# 或者list_float = [float(e) for e in list_str] 也可以
arr_float = np.array(list_float) # 是数组类型,但是每一个元素都是浮点数
print 'arr_float.astype:', arr_float.astype
2. 将二维数组转化为列表形式list(list)
本人遇到的问题是,如果直接将二维数组写入文件,那么每一行(一条记录)无法写入一行,那个如果下次直接使用f.readlines()函数,获得的每一行并不是一个样本,虽然使用正则表达式和re模块可以解决,不过有些麻烦,因此,本人将每条记录用列表(list)表示,所有样本用list表示。因此将数组转化为列表的方法:
list_data = []
num_rows, num_cols = shape(array_data)
for i in range(num_rows):
list_rows = []
for j in range(num_cols):
list_rows.append(round(array_data[i, j], 4))
list_data.append(list_rows)
f = open('/usr/data/test.txt', 'w')
for i in list_data:
print >> f, i # i表示一条样本,将会在文件中一行出现(不会换行)
3. Python中split()函数不支持多分隔符
python的字符串中的split()函数,默认只能有一个分隔符(不像Java中split()有多个分隔符),那个此函数解决不了从“1+2-3*4”字符串中提取数值列表[‘1’, ‘2’, '3', '4']的问题,好在re模块可以解决这个问题,re.split('[]', str) 可以中可以用多个分隔符作为参数,例如
def split_re():
import re
str_ings = '1+2-3*4'
str_list = re.split('[+|\-|*]', str_ings) # '-'是特殊字符,需要加转义符号'\'
print 'str_list:', str_list
4. 二维数组存入文件中,保证每一行表示一个样例
机器学习/数据挖掘的数据预处理过程中,产生的中间结果通常为二维数组(矩阵)类型,当特征数很多时(如>100),将其保存在文件中,无法放入一行,下次用readlines()函数读取时,得到的每一行并不是一个样本,这给后续数据使用带来麻烦,这里总结了,如何将 二维数组数据写入文件(每一行保存一个样本),以及如何从文件中读取数据,转为后二维数组类型,共后续的机器学习工作~
'''
将二维数组数据保存至文件中:
为避免一个样本(一行)不能写入保存在文件中一行,本文先做数据转化
① 首先将二维数组(矩阵形式)转化为列表类型,同时每一行也是列表类型list_data;
② 将list类型的数据,保存到数组中
'''
def writeDataToFile(filename, array_data):
# step1: data type convert from array to list
list_data = []
num_rows, num_cols = shape(array_data)
for i in range(num_rows):
list_rows = []
for j in range(num_cols):
list_rows.append(round(array_data[i, j], 4)) # 'round()' function convert accuracy of float data
list_data.append(list_rows)
# step2: write list_data to file
f = open(filename, 'w')
for i in list_data:
print >> f, i # '>>' operation write 2-dimensions array to file directly
print 'Congratulations, write file %s has completed!' % filename
'''
从列表文件中读取数据,转化为二维数组形状
做类型转换后,转为后数组形式,将其中的字符串转换为数组or整数
① 读取数据,提取数据,去除无用字符translate,由字符串转化为浮点数map,得到列表结果
② 将列表转化为浮点数
'''
def readDataFromFile(filename):
# step1: read data by rows, delete unused chars, convert element type
f = open(filename)
list_data = f.readlines() # fetch string list, each row is string type, not list type
allchars = string.maketrans("", "")
array_list = []
for line in list_data:
str_ings = line.translate(allchars, '[]')
str_list = str_ings.split(',') # split string into string list
float_list = map(float, str_list) # return float element list
array_list.append(float_list)
# step2: convert float element list to float element array
array_data = np.array(array_list)
return array_data
上面的writeDataToFile()函数存在一些严重的不足:
① python中的赋值实际上是传递地址,即'b = a', 并不是把a内存中的值赋给b,而是把a的地址传给b,即a和b共享一个地址。writeDataToFile()函数中多次操作list_rows变量并置空,导致占用的内存没有及时释放,当保存大数据时,很快就把内存占满,宕机。可使用gc(garbage collector)模块释放内存,具体操作:del list_rows; gc.collect(), 但是带来的问题是存储数据的时间会增长(本实验时间增长5倍左右)
② 没必要将转换的行列表,再写入另一个列表list_data中,这样只会徒增内存,增加计算量,可以直接将每一次得到的list_rows写入文件,具体的改进:
'''
将二维数组数据保存至文件中:
为避免一个样本(一行)不能写入保存在文件中一行,本文先做数据转化
① 首先将二维数组的每一行转化为列表形式;
② 将得到的行列表直接写入文件,这样就完成了一条样本保存在文件的一行中;
'''
def writeDataToFile(filename, array_data):
saveStartTime = time.time()
# step1: data type convert from array to list
num_rows, num_cols = shape(array_data)
# step2: write list_data to file
f = open(filename, 'w')
for i in range(num_rows):
list_rows = []
for j in range(num_cols):
list_rows.append(round(array_data[i, j], 4)) # 'round()' function convert accuracy of float data
print >> f, list_rows # '>>' operation write list data to file directly
del list_rows
gc.collect() # release memory, but lead to time overhead, while data column is small, you can't use this function
print 'Congratulations, write file %s has completed!' % filename
saveEndTime = time.time()
print 'save data to file run time totally %s s' % (saveEndTime - saveStartTime)
上面中readDataFromFile()文件中,也存在一些缺点,f.readlines()函数会读取全部文件(字符串列表),容易发生MemoryError,可以改进
def readDataFromFile1(filename):
readStartTime = time.time()
# step1: read data by rows, delete unused chars, convert element type
f = open(filename)
allchars = string.maketrans("", "")
array_list = []
line = f.readline() # not use f.readlines()
while line:
str_ings = line.translate(allchars, '[]')
str_list = str_ings.split(' ') # split string into string list
float_list = map(float, str_list) # return float element list
array_list.append(float_list)
del str_ings, str_list, float_list, line
gc.collect() # release memory at each iteration
line = f.readline()
# step2: convert float element list to float element array
array_data = np.array(array_list)
del array_list
gc.collect()
print 'Congratulations, read data from file %s has completed! Now, return array_type data' % filename
readEndTime = time.time()
print 'read data from file run time totally: %s s' % (readEndTime - readStartTime)
return array_data