前言:对标最近的需求,需要在tf中实现诸如SQL中的order by col1, col2 或 pandas中的sort_index([col1, col2],ascending=False)原理;另外将tensorflow中将placeholder读取方式变成tf.recorder方式。
1) 首先,明确SQL中的order by col1, col2 和pandas中的sort_index([col1, col2])的原理都是按照col1,col2这样的顺序,降序排列。例如这两列是user_id, phone_number,则会先根据user_id排序,然后同一user_id的数据再按照phone_number的顺序降序排列。
而查资料发现:关于排序 tensorflow的API中只有tf.sort() 和tf.argsort()这两个大类函数,考虑过分别对两列进行argsort排列,取出相应的index索引list,后来想想还是不能符合我的预期。后来发现:可以将两列进行拼接(user_id*phone_number)生成新的一列,然后直接根据这一派生的列进行argsort(),并将得到的顺序索引index list应用于其它的特征列上即可实现,对不同的用户的数据按照user_id和phone_number进行降序排列。
sort_index = tf.argsort(cols[0], direction='DESCENDING', axis=0) # cols[0]就是派生的新列特征
cols_sorted = tf.gather(cols, sort_index, axis=0) # cols是所有的数据的宽表数据
经过上述的思路可以实现,对标SQL中的order by col1, col2 或 pandas中的sort_index([col1, col2],ascending=False)原理。
2)数据读取的更换:
之前使用tensorflow的时候,一般是利用的placeholder占位符的思想,但是占位符的原理存在一些弊端,如果我们要使用GPU资源的话,占位符并不是最优的方法,于是学习进行更换。以下选择TableRecoderReader方式,可以参考以下链接:TF的读取方式
以下主要写一些自己的理解:
file_queue = tf.train.string_input_producer([table], num_epochs=num_epochs)
reader = tf.TableRecordReader(csv_delimiter='\t', num_threads=12, capacity=batch_size * 12
, slice_count=worker_count, slice_id=slice_id)
key, value = reader.read_up_to(file_queue, num_records=batch_size)
defa_record = [['']] + [['0']] * 185 # 此处将value拆成186列
cols = tf.decode_csv(value, record_defaults=defa_record, field_delim='\t') ##record_defaults=[[], []]文件读取后的数据默认格式,文件有几列返回值就有几个,
##默认是英文逗号分隔,可以指定,此处指定的是换行符
* 注意decode_csv会按照default设置的记录,将读入文件队列的value进行每列每列的分割,其中会将每一列写成一个单独的tensor.
将csv转换成tensors,每一列对应一个tensor
Args:
records: string类型的tensor,每一个string是具有csv类似格式的。
record_defaults: tensor的默认值,如果records为空。
field_delim: 默认分隔符,csv为,。
name: 操作符名称
Retures:
返回tensor列表,每一个tensor类型和record_defaults相同,每一个tensor与 records具有相同的大小。
* 另外也有涉及到tf.TextLineReader() 可以直接read from CSV or txt。
本文也参考了以下博客,https://saicoco.github.io/tf3/