Spark MLlib 的官方例子里面提供的数据大部分是 libsvm 格式的。这其实是一种非常蛋疼的文件格式,和常见的二维表格形式相去甚远,下图是里面的一个例子:

完整代码

libsvm 文件的基本格式如下:

<label> <index1>:<value1> <index2>:<value2>…

label 为类别标识,index 为特征序号,value 为特征取值。如上图中第一行中 0 为标签,128:51 表示第 128 个特征取值为 51 。

Spark 固然提供了读取 libsvm 文件的API,然而如果想把这些数据放到别的库 (比如scikit-learn) 中使用,就不得不面临一个格式转换的问题了。由于 CSV 文件是广大人民群众喜闻乐见的文件格式,因此分别用 Python 和Java 写一个程序来进行转换。我在网上查阅了一下,基本上全是 csv 转 libsvm,很少有 libsvm 转 csv 的,唯一的一个是 phraug库中的libsvm2csv.py 。但这个实现有两个缺点: 一个是需要事先指定维度; 另一个是像上图中的特征序号是 128 - 658 ,这样转换完之后 0 - 127 维的特征全为 0,就显得多余了,而比较好的做法是将全为 0 的特征列一并去除。下面是基于 Python 的实现:

import sys
import csv
import numpy as np def empty_table(input_file): # 建立空表格, 维数为原数据集中最大特征维数
max_feature = 0
count = 0
with open(input_file, 'r', newline='') as f:
reader = csv.reader(f, delimiter=" ")
for line in reader:
count += 1
for i in line:
num = int(i.split(":")[0])
if num > max_feature:
max_feature = num return np.zeros((count, max_feature + 1)) def write(input_file, output_file, table):
with open(input_file, 'r', newline='') as f:
reader = csv.reader(f, delimiter=" ")
for c, line in enumerate(reader):
label = line.pop(0)
table[c, 0] = label
if line[-1].strip() == '':
line.pop(-1) line = map(lambda x : tuple(x.split(":")), line)
for i, v in line:
i = int(i)
table[c, i] = v delete_col = []
for col in range(table.shape[1]):
if not any(table[:, col]):
delete_col.append(col) table = np.delete(table, delete_col, axis=1) # 删除全 0 列
with open(output_file, 'w') as f:
writer = csv.writer(f)
for line in table:
writer.writerow(line) if __name__ == "__main__":
input_file = sys.argv[1]
output_file = sys.argv[2]
table = empty_table(input_file)
write(input_file, output_file, table)

以下基于 Java 来实现,不得不说 Java 由于没有 Numpy 这类库的存在,写起来要繁琐得多。

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class LibsvmToCsv {
public static void main(String[] args) throws IOException { String src = args[0];
String dest = args[1]; double[][] table = EmptyTable(src);
double[][] newcsv = NewCsv(table, src);
write(newcsv, dest);
} // 建立空表格, 维数为原数据集中最大特征维数
public static double[][] EmptyTable(String src) throws IOException {
int maxFeatures = 0, count = 0;
File f = new File(src);
BufferedReader br = new BufferedReader(new FileReader(f));
String temp = null;
while ((temp = br.readLine()) != null){
count++;
for (String pair : temp.split(" ")){
int num = Integer.parseInt(pair.split(":")[0]);
if (num > maxFeatures){
maxFeatures = num;
}
}
}
double[][] emptyTable = new double[count][maxFeatures + 1];
return emptyTable;
} public static double[][] NewCsv(double[][] newTable, String src) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(src)));
String temp = null;
int count = 0;
while ((temp = br.readLine()) != null){
String[] array = temp.split(" ");
double label = Integer.parseInt(array[0]);
for (String pair : Arrays.copyOfRange(array, 1, array.length)){
String[] pairs = pair.split(":");
int index = Integer.parseInt(pairs[0]);
double value = Double.parseDouble(pairs[1]);
newTable[count][index] = value;
}
newTable[count][0] = label;
count++;
} List<Integer> deleteCol = new ArrayList<>(); // 要删除的全 0 列
int deleteColNum = 0; coll:
for (int col = 0; col < newTable[0].length; col++){
int zeroCount = 0;
for (int row = 0; row < newTable.length; row++){
if (newTable[row][col] != 0.0){
continue coll; // 若有一个值不为 0, 继续判断下一列
} else {
zeroCount++;
}
} if (zeroCount == newTable.length){
deleteCol.add(col);
deleteColNum++;
}
} int newColNum = newTable[0].length - deleteColNum;
double[][] newCsv = new double[count][newColNum]; // 新的不带全 0 列的空表格
int newCol = 0; colll:
for (int col = 0; col < newTable[0].length; col++){
for (int dCol : deleteCol){
if (col == dCol){
continue colll;
}
} for (int row = 0; row < newTable.length; row++){
newCsv[row][newCol] = newTable[row][col];
}
newCol++;
}
return newCsv;
} public static void write(double[][] table, String path) throws FileNotFoundException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));
try{
for (double[] row : table){
int countComma = 0;
for (double c : row){
countComma ++;
bw.write(String.valueOf(c));
if (countComma <= row.length - 1){
bw.append(',');
}
}
bw.flush();
bw.newLine();
}
} catch (IOException e){
e.printStackTrace();
} finally {
try{
if (bw != null){
bw.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
}
}

/

LibSVM文件转换为csv格式的更多相关文章

  1. 如何将EDI报文转换为CSV格式文件?

    如果您对EDI项目实施有一定的了解,想必您一定知道,在正式开始EDI项目实施之前,都会有EDI顾问与您接洽,沟通EDI项目需求.其中,会包含EDI通信双方使用哪种传输协议,传输的报文是符合什么标准的, ...

  2. C# 将PDF文件转换为word格式

    Pdf(Portable Document Format)意为“便携式文档格式”,是现在最流行的文件格式之一,它有很多优点如:尺寸较小.阅读方便.操作系统平台通用等,非常适合在网络上传播和使用.如今在 ...

  3. java 调用OpenOffice将word格式文件转换为pdf格式

    一:环境搭建 OpenOffice 下载地址http://www.openoffice.org/ JodConverter 下载地址http://sourceforge.net/projects/jo ...

  4. 将 Graphviz .dot 文件转换为其他格式的图像

    参考: Graphviz: How to go from .dot to a graph? 将 Graphviz .dot 文件转换为其他格式的图像 在Linux系统下,使用以下命令: dot -Tp ...

  5. PHP 将amr音频文件转换为mp3格式

    说下整体思路 1.服务器安装ffmpeg 2.使用ffmpeg -i 指令来转换amr为mp3格式(这个到时候写在PHP代码中,使用exec函数执行即可) 3.在网页端使用HTML5的audio标签来 ...

  6. excel批量转换为CSV格式,xls批量导出csv格式

    工具/原料   excel 2013 地址链接:http://pan.baidu.com/s/1c1ZABlu 密码:d3rc 方法/步骤     首选我们把需要导出为CVS的Excel文件整理集中到 ...

  7. 将dos格式文件转换为unix格式

    在windows下换行符是\r\n,表示回到行首并换到下一行 而unix系统中换行符是\n 这样就存在一个问题,在windows上的文档到了unix上可能就无法使用了 针对这个情况有几种解决办法: 1 ...

  8. 如何使用python把json文件转换为csv文件

    @ 目录 了解json整体格式 转换格式 提取key和value 使用pandas写入csv 了解json整体格式 这里有一段json格式的文件,存着全球陆地和海洋的每年异常气温(这里只选了一部分): ...

  9. 将excel2003文档文件转换为excel2007格式

    在sharepoint 2010 中,excel2007或excel 2010文档格式,支持web app 应用,能够在浏览器在线打开,查看,但excel 2003格式的文档只能用office客户端打 ...

随机推荐

  1. BZOJ2563: 阿狸和桃子的游戏 贪心

    Description 阿狸和桃子正在玩一个游戏,游戏是在一个带权图G=(V, E)上进行的,设节点权值为w(v),边权为c(e).游戏规则是这样的: 1. 阿狸和桃子轮流将图中的顶点染色,阿狸会将顶 ...

  2. LeetCode——Find Bottom Left Tree Value

    Question Given a binary tree, find the leftmost value in the last row of the tree. Example 1: Input: ...

  3. navicat Window . MAC版常用快捷键

    navicat 结合快捷键 1.ctrl+q 打开查询窗口 2.ctrl+/ 注释sql语句 3.ctrl+shift +/ 解除注释 4.ctrl+r 运行查询窗口的sql语句 5.ctrl+shi ...

  4. BZOJ 4571 【SCOI2016】 美味

    题目链接:美味 如果题目里面没有那个\(a_i\),这道题就可以直接在\(Trie\)树上走一走就做完了.现在多了个\(a_i\),\(Trie\)树就无能为力了. 我们考虑一下在\(Trie\)树上 ...

  5. Jenkins 对项目持续集成的配置之二 API接口自动化 Ant+Jmeter

    先介绍一下Ant+Jmeter 略 我的另一篇文章有讲在linux上部署ant + jmeter以满足CI持续化集成 https://www.cnblogs.com/qianjinyan/p/9067 ...

  6. Spring 注解 @Resource和@Autowired

    @Resource和@Autowired两者都是做bean的注入使用. 其实@Resource并不是Spring的注解,他的包是javax.annotation.Resource 需要导入.但是Spr ...

  7. Java数据类型转换(自动转换和强制转换)

    数据类型的转换,分为自动转换和强制转换.自动转换是程序在执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;强制类型转换则必须在代码中声明,转换顺序不受限制. 自 ...

  8. 基因家族收缩和扩张分析 & Selective loss pathway & 泛基因组

    套路 这通常就是基因组组装后的必做分析,通过比较基因组学的手段进行分析,可以知道所研究物种在进化过程中哪些核心基因家族发生了变化,从而导致了其特殊的适应性机制的形成. 参考: Extremotoler ...

  9. pip 源 替换国内源

    网上收集来的pip源地址: 阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simp ...

  10. LeetCode--067--二进制求和

    问题描述: 给定两个二进制字符串,返回他们的和(用二进制表示). 输入为非空字符串且只包含数字 1 和 0. 示例 1: 输入: a = "11", b = "1&quo ...