1
我想用numpy.loadtxt
來閱讀CSV文件。我知道我可以用usecols
參數指定我想要讀取的列。但是,我真正想要做的是指定一個列表而不是來閱讀。這是因爲我實際上並不知道我的文件將包含多少列。numpy.loadtxt - 否定usecols?
除了讀取文件的前幾行,確定列的總數,然後手動計算要讀取的一組列以外,是否有任何方法可以執行此操作?
我想用numpy.loadtxt
來閱讀CSV文件。我知道我可以用usecols
參數指定我想要讀取的列。但是,我真正想要做的是指定一個列表而不是來閱讀。這是因爲我實際上並不知道我的文件將包含多少列。numpy.loadtxt - 否定usecols?
除了讀取文件的前幾行,確定列的總數,然後手動計算要讀取的一組列以外,是否有任何方法可以執行此操作?
不是沒有閱讀第一行,正如你所提到的。
但是,它可能是更容易做到:
do_not_read_cols = [3, 4, 9]
data = np.loadtxt('filename')
data = np.delete(data, do_read_cols, axis=1)
這會不會是可怕的內存效率,但loadtxt
不會嘗試是非常節省內存開始。除非要刪除大部分列,否則在調用loadtxt
時會比使用delete
後續的臨時副本更多地使用內存。
下面關於我的評論擴大,如果你想節省內存,並且不希望使用pandas
,另一種選擇是這樣的:(注:寫了一個有點拖泥帶水)
import numpy as np
def generate_text_file(length=1e6, ncols=20):
data = np.random.random((length, ncols))
np.savetxt('large_text_file.csv', data, delimiter=',')
def iter_loadtxt(filename, delimiter=',', skiprows=0, skipcols=None,dtype=float):
if skipcols is None:
skipcols = []
def iter_func():
with open(filename, 'r') as infile:
for _ in range(skiprows):
next(infile)
for line in infile:
line = line.rstrip().split(delimiter)
for i, item in enumerate(line):
if i in skipcols:
continue
yield dtype(item)
iter_loadtxt.rowlength = len(line) - len(skipcols)
data = np.fromiter(iter_func(), dtype=dtype)
data = data.reshape((-1, iter_loadtxt.rowlength))
return data
#generate_text_file()
data = iter_loadtxt('large_text_file.csv')
謝謝,但不幸的是記憶效率是首先這樣做的全部原因,所以這對我不起作用。 – Nils
@Nils - 如果你擔心內存效率,不要使用'loadtxt'。它將使用大約8倍的內存來加載陣列。 (不要插我自己的答案,但看到這個例子:http://stackoverflow.com/questions/8956832/python-out-of-memory-on-large-csv-file-numpy/8964779#8964779)如果你想走那條路線,熊貓實際上是相當有記憶效率的。由於'pandas'有效地將_列每個列存儲在其自己的數組中,因此刪除一組列不需要複製。或者,您可以用幾行編寫自己的加載生成器,並用'np.fromiter'將其讀入。 –
我正在修復一些現有的代碼,所以我想避免重寫整個方法來完全使用不同的程序包。但是,如果這是我的決定,我可能首先使用熊貓,是的。 :) – Nils