ero*_*934 6 python parsing fixed-width pandas
我有一个相当大的固定宽度文件(~30M 行,4gb),当我尝试使用 pandas read_fwf() 创建一个 DataFrame 时,它只加载了文件的一部分,并且很好奇是否有人遇到过类似的问题此解析器不读取文件的全部内容。
import pandas as pd
file_name = r"C:\....\file.txt"
fwidths = [3,7,9,11,51,51]
df = read_fwf(file_name, widths = fwidths, names = [col0, col1, col2, col3, col4, col5])
print df.shape #<30M
Run Code Online (Sandbox Code Playgroud)
如果我天真地使用 read_csv() 将文件读入 1 列,则所有文件都将被读取到内存中,并且不会丢失数据。
import pandas as pd
file_name = r"C:\....\file.txt"
df = read_csv(file_name, delimiter = "|", names = [col0]) #arbitrary delimiter (the file doesn't include pipes)
print df.shape #~30M
Run Code Online (Sandbox Code Playgroud)
当然,如果没有看到文件的内容或格式,它可能与我的事情有关,但想看看过去是否有人遇到过任何问题。我做了一个健全性检查并测试了文件深处的几行,它们似乎都被正确格式化(当我能够使用相同的规范将其拉入带有 Talend 的 Oracle DB 时进一步验证)。
如果有人有任何想法,请告诉我,通过 Python 运行所有内容而不是在我开始开发分析时来回走动会很棒。
输入文件的几行对于查看日期的外观很有用。尽管如此,我生成了一些与您具有类似格式(我认为)的随机文件,并将其应用pd.read_fwf到其中。这是生成并读取它的代码:
从随机导入随机
import pandas as pd
file_name = r"/tmp/file.txt"
lines_no = int(30e6)
with open(file_name, 'w') as f:
for i in range(lines_no):
if i%int(1e5) == 0:
print("Writing progress: {:0.1f}%"
.format(float(i) / float(lines_no)*100), end='\r')
f.write(" ".join(["{:<10.8f}".format(random()*10) for v in range(6)])+"\n")
print("File created. Now read it using pd.read_fwf ...")
fwidths = [11,11,11,11,11,11]
df = pd.read_fwf(file_name, widths = fwidths,
names = ['col0', 'col1', 'col2', 'col3', 'col4', 'col5'])
#print(df)
print(df.shape) #<30M
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下,它看起来工作正常。我使用 Python 3.4、Ubuntu 14.04 x64 和 pandas 0.15.1。创建文件并使用 读取它需要一段时间pd.read_fwf。但它似乎有效,至少对我和我的设置来说是这样。
结果是:(30000000, 6)
创建的示例文件:
7.83905215 9.64128377 9.64105762 8.25477816 7.31239330 2.23281189
8.55574419 9.08541874 9.43144800 5.18010536 9.06135038 2.02270145
7.09596172 7.17842495 9.95050576 4.98381816 1.36314390 5.47905083
6.63270922 4.42571036 2.54911162 4.81059164 2.31962024 0.85531626
2.01521946 6.50660619 8.85352934 0.54010559 7.28895079 7.69120905
Run Code Online (Sandbox Code Playgroud)