我有一个像这样的简单CSV文件:
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Note ,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
1,,,,,X,,,,,,,,X,,,,,,,,X,,,,,,,,X,,,
2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
我需要将其解析为包含 1
-s的二维数组,其中X为 0
,否则忽略标题/额外行。
在阅读 csv
模块上的文档后,我写了一个简单的脚本,如下所示:
import csv
csvfile = open('input.csv', 'rb')
reader = csv.reader(csvfile,dialect='excel', delimiter=' ', quotechar='|')
data = []
rowCount = 0
for row in reader:
if(rowCount > 2): #skip first 3 rows (2 empty and 1 label)
dataRow = []
for i in xrange(1,len(row[0])):#skip 1st label column
dataRow.append(1 if row[0][i] == 'X' else 0) #append 1s for X, 0s otherwise
data.append(dataRow)
rowCount += 1
print data
这给了我预期的输出:
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
代表
,,,,,X,,,,,,,,X,,,,,,,,X,,,,,,,,X,,,
三元条件可以写成ord(row[0][i])/88
,但是可以将每个字符串行映射到1和0的整数行吗?
是否有更多' pythonic'写这个的方式?
答案 0 :(得分:6)
您应该使用delimiter=','
:
reader = csv.reader(csvfile, dialect='excel', delimiter=',', quotechar='|')
实际上:
dialect='excel', delimiter=','
是默认值,您的示例文件不需要quotechar='|'
(如果需要,请保留)。所以这个更短:
reader = csv.reader(csvfile)
丢掉前三行:
[next(reader) for _ in range(3)]
阅读所有专栏:
data = [[1 if entry=='X' else 0 for entry in row[1:]] for row in reader]
这相当于:
data = []
for row in reader:
data.append([1 if entry=='X' else 0 for entry in row[1:]])
当然,请在dedent后自动关闭打开文件:
with open('input.csv', 'rb‘) as csvfile:
# Put the rest of the algorithm here.
# The file is closed automatically just because continuing detended.
这是context manager的主要示例。
全部放在一起:
import csv
with open('input.csv', 'rb') as csvfile:
reader = csv.reader(csvfile)
[next(reader) for _ in range(3)]
data = [[1 if entry=='X' else 0 for entry in row[1:]] for row in reader]
答案 1 :(得分:4)
首先,跳过三行可以像:
for _ in range(3):
next(reader)
然后您可以在其余部分使用list comprehension:
data = [[int(cell == 'X') for cell in line[1:]] for line in reader]
这为您提供了一个列表列表:
>>> data
[[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
如果效率很重要并且线条较长,则使用itertools.islice
可以在不创建新列表的情况下对每一行进行切片。
请注意,您的delimiter
和quotechar
设置似乎与示例文件不匹配,因此您可能需要仔细检查一下。
答案 2 :(得分:1)
有一件事我想添加到@jonrsharpe的答案。
使用文件的Pythonic方式如下。 这将在您完成计算时为您关闭文件
angular.module('ArtistController', []).controller('ArtistController', ['$scope', 'Artist', '$location', '$routeParams',
function ($scope, Artist, $location, $routeParams) {
$scope.getArtistInfo = function (params) {
$scope.artist = Artist.getArtistInfo(params);
}
$scope.params = $routeParams;
}
]);
答案 3 :(得分:0)
numpy.genfromtxt()
DATA = np.genfromtxt( aFH, # aFH = open( <aFileNAME>, "r" )
#kiprows = 1, # DeprecationWarning: The use of `skiprows` is deprecated, it will be removed in numpy 2.0.
skip_header = 3, # twice "..." + "Note,1,2,3.."
delimiter = ",",
converters = { 1: lambda aString: mPlotDATEs.date2num( datetime.datetime.strptime( aString[1:-1], "%m/%d/%y %H:%M" ) ),
0: lambda aString: float( aString[1:-1] )
} # left as an example of powers the genfromtxt()'s inline conversters create
)
print "DATA has shape of ", DATA.shape
aFH.close()
converters
(asDict)是关键字(指定每列) - 即可以将 X
-s后处理为< strong> 1
-s和 isBlank
-s到 0
-s
根据 numpy
,任何严重的数字运算都是可见的或不可见的。因此,导入模块的足迹不会导入 pandas
(非常智能且非常强大),只需导入文本行而无需进一步使用高级{{ 1}}能力。
此外,如果您的 DataFrame
变得越来越大,您可能会从其他更智能的 numpy
功能中受益。从您的示例数据中可以看出,这是使用 SPARSE-MATRICE 的典型情况,您不需要支付与处理差不多相关的巨额开销 - 空 -cells( DATA.size
-s)。
这可能会给你提供比 bool -ean-MASK数组更加紧凑的内存解决方案,它仍然在0-cell-s上花费超过几位网格化( DENSE -MATRIX)。
0
- ic方法吗?希望这不会引发火焰战争。因此,作为简约视图,我们假设 python
-loops被避免(第一次加 - 正式和性能方面),单线 - 民粹主义者可能也很高兴,因为整个导入过程需要一行(有点健谈,但仍有一行...... SLOC-line 如果有人真正关心:o))。 最后 for
-inliners非常聪明且功能强大 lambda
-ic non-plus-ultra(get爱上他们,因为他们都给你巨大的力量,所以,所以,所以, python
-ic(虽然原则上这些“查克诺里斯”的代码起源于LISP在上世纪50年代后期开发的关于高效软件设计的科学))