开发者社区 问答 正文

Python:当读取一个没有默认分隔符的文件(包含数百万条记录)并将其放入dataframe (pa

Python:在没有默认分隔符(包含数百万条记录)的情况下读取文件并将其放入“数据框架(panda)”中,最有效的方法是什么? 文件是:"file_sd.txt"

 A123456MESTUDIANTE 000-12
 A123457MPROFESOR   003103
 I128734MPROGRAMADOR00-111
 A129863FARQUITECTO 00-456
# Fields and position:
# - Activity Indicator :  indAct     -> 01 Character
# - Person Code        :  codPer     -> 06 Characters
# - Gender (M / F)     :  sex        -> 01 Character
# - Occupation         :  occupation -> 11 Characters
# - Amount(User format):  amount     -> 06 Characters (Convert to Number)

我不确定。这是最好的选择吗?

 import pandas as pd 
 import numpy as np

 def stoI(cad):
     pos =  cad.find("-")
     if pos < 0: return int(cad)  
     return int(cad[pos+1:])*-1 

 #Read Txt
 data = pd.read_csv(r'D:\file_sd.txt',header = None)
 data_sep = pd.DataFrame(
     {
         'indAct'   :data[0].str.slice(0,1),
         'codPer'   :data[0].str.slice(1,7),
         'sexo'     :data[0].str.slice(7,8),
         'ocupac'   :data[0].str.slice(8,19),
         'monto'    :np.vectorize(stoI)(data[0].str.slice(19,25))
     })
 print(data_sep)

   indAct  codPer sexo       ocupac  monto
 0      A  123456    M  ESTUDIANTE     -12
 1      A  123457    M  PROFESOR      3103
 2      I  128734    M  PROGRAMADOR   -111
 3      A  129863    F  ARQUITECTO    -456

这个7百万行的解决方案。结果是:

%timeit df_slice()
11.1 s ± 166 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

问题来源StackOverflow 地址:/questions/59383835/python-efficiency-when-reading-a-file-without-a-default-delimiter-with-millions

展开
收起
kun坤 2019-12-26 15:50:18 1191 分享 版权
1 条回答
写回答
取消 提交回答
  • 您有一个固定宽度的文件,因此应该使用适当的pd。read_fwf读者。在本例中,我们将指定属于每个字段和列名的字符数。

    df = pd.read_fwf('test.txt', header=None, widths=[1, 6, 1, 11, 6])
    df.columns = ['indAct' ,'codPer', 'sexo', 'ocupac', 'monto']
    #  indAct  codPer sexo       ocupac   monto
    #0      A  123456    M   ESTUDIANTE  000-12
    #1      A  123457    M     PROFESOR  003103
    #2      I  128734    M  PROGRAMADOR  00-111
    #3      A  129863    F   ARQUITECTO  00-456
    

    现在您可以修复字段的dtype。通过去除0并调用pd.to_numeric,可以将“monto”转换成数字。

    df['monto'] = pd.to_numeric(df['monto'].str.strip('0'), errors='coerce')
    #  indAct  codPer sexo       ocupac  monto
    #0      A  123456    M   ESTUDIANTE    -12
    #1      A  123457    M     PROFESOR   3103
    #2      I  128734    M  PROGRAMADOR   -111
    #3      A  129863    F   ARQUITECTO   -456
    

    正如您的评论所指出的,这可能在表面上看起来比较慢。优点是pd。read_fwf作为一种I/O操作,具有大量的自动数据清理功能。 在许多对象列完全包含整个字符限制、没有丢失数据的情况下,字符串切片具有优势。但是对于一般的未知数据集,您需要摄取和ETL,一旦开始将字符串剥离和类型转换附加到每个列,您可能会发现指定的panda I/O操作是最佳选择。

    2019-12-26 15:50:25
    赞同 展开评论