Как заполнить NA в пропущенном месте текстового файла, используя список Python - PullRequest
0 голосов
/ 18 мая 2018

У меня есть набор данных в необработанном текстовом файле (это файл журнала), я готовлю список python, используя это текстовое чтение файла построчно, с этим списком я создам кадр данных, используя pyspark. Если вы видите набор данных, некоторыев соответствующем столбце отсутствуют значения, я хочу заполнить его "NA". Это образец набора данных, отсутствующее значение может быть в любом столбце, столбцы разделены пробелами

==============================================
empcode   Emnname   Date       DESC
12d      sf        2018-02-06      dghsjf  
asf2     asdfw2    2018-02-16      fsfsfg  
dsf21    sdf2      2016-02-06      sdgfsgf
sdgg     dsds      dkfd-sffddfdf   aaaa
dfd      gfg       dfsdffd         aaaa
df                 dfdf            efef
4fr                                freff         
----------------------------------------------

MyCode:

path="something/demo.txt"
EndStr="----------------------------------------------"
FilterStr="=============================================="
findStr="empcode   Emnname"

def PrepareList(findStr):
  with open(path) as f:
    out=[]
    for line in f:
        if line.rstrip()==Findstr:
            #print(line)
            tmp=[]
            tmp.append(re.sub("\s+",",",line.strip()))
            #print(tmp)
            for line in f:
                if line.rstrip()==EndStr:
                    out.append(tmp)
                    break

                tmp.append(re.sub("\s+",",",line.strip()))
            return (tmp)
  f.close()  
LstEmp=[]
LstEmp=prepareDataset("empcode   Emnname   Dept   DESC")
print(LstEmp)

Мой вывод:

['empcode,Emnname,Date,DESC', 
 '12d,sf,2018-02-06,dghsjf',
 'asf2,asdfw2,2018-02-16,fsfsfg',
 'dsf21,sdf2,2016-02-06,sdgfsgf',
 'sdgg,dsds,dkfd-sffddfdf,aaaa',
 'dfd,gfg,dfsdffd,aaaa',
 'df,dfdf,efef',
 '4fr,freff']  

Ожидаемый вывод:

['empcode,Emnname,Date,DESC', 
 '12d,sf,2018-02-06,dghsjf',
 'asf2,asdfw2,2018-02-16,fsfsfg',
 'dsf21,sdf2,2016-02-06,sdgfsgf',
 'sdgg,dsds,dkfd-sffddfdf,aaaa',
 'dfd,gfg,dfsdffd,aaaa',
 'df,NA,dfdf,efef',
 '4fr,NA,NA,freff']

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Здесь я попытался следовать общему подходу, при котором вам не нужно предварительно программировать интервалы столбцов в вашем коде.Для возврата dataframe вы можете использовать pd.read_csv с stringio.Пожалуйста, измените путь в соответствии с местоположением вашего файла.И этот код расширен от вашего кода, чтобы вам было проще его понять, в противном случае есть более красивые способы написать ту же логику

    import re
import pandas as pd
import StringIO
path = "/home/clik/clik/demo.txt"
EndStr = "------------------------------"
FilterStr = "=================="
FindStr = "empcode   Emnname"


def match(sp1, sp2):
    disjunct = max(sp1[0] - sp2[1], sp2[0] - sp1[1])
    if disjunct >= 0:
        return -abs((sp1[0]+sp1[1])/2.0 - (sp2[0]+sp2[1])/2.0)
    return float(disjunct) / min(sp1[0] - sp2[1], sp2[0] - sp1[1])


def PrepareList():
    with open(path) as f:
        out = []
        for i, line in enumerate(f):
            print line.rstrip()
            if line.rstrip().startswith(FindStr):
                print(line)
                tmp = []
                col_spans = [m.span() for m in re.finditer("[^\s][^\s]+", line)]
                tmp.append(re.sub("\s+", ",", line.strip()))
                # print(tmp)
                for line in f:
                    if line.rstrip().startswith(EndStr):
                        out.append(tmp)
                        break
                    row = [None] * len(col_spans)
                    for m in re.finditer("[^\s][^\s]+", line):
                        colmatches = [match(m.span(), cspan) for cspan in col_spans]
                        max_index = max(enumerate(colmatches), key=lambda e: e[1])[0]
                        row[max_index] = m.group() if row[max_index] is None else (row[max_index] + ' ' + m.group())
                    tmp.append(','.join(['NA' if e is None else e for e in row]))
                    #tmp.append(re.sub("\s+", ",", line.strip()))
                #for pandas dataframe
                #return pd.read_csv(StringIO.StringIO('\n'.join(tmp)))

                #for returning list of tuples
                return map(tuple, tmp)
                #for returning list of list
                #return tmp
    f.close()


LstEmp = PrepareList()

для покрытия списка кортежей в фрейме данных pyspark, вот учебникhttp://bigdataplaybook.blogspot.in/2017/01/create-dataframe-from-list-of-tuples.html

0 голосов
/ 19 мая 2018

Из набора данных видно, что текст в полях имеет переменную длину, а сами поля начинаются и заканчиваются в фиксированной позиции.Обычно это происходит с разделенными табуляцией полями.

==============================================
empcode   Emnname   Date       DESC
12d      sf        2018-02-06      dghsjf  
asf2     asdfw2    2018-02-16      fsfsfg  
dsf21    sdf2      2016-02-06      sdgfsgf

В этом случае должно работать следующее:

for line in f:
    if line.rstrip()==Findstr:
        tmp=[]
        tmp.append(re.sub("\t",",",line.strip()))
        #print(tmp)
        for line in f:
            if line.rstrip()==EndStr:
                out.append(tmp)
                break

            tmp.append(re.sub("\t",",",line.strip()))
        return (tmp)

Я заменил \s в вашем коде на \t иудалено +.В регулярном выражении Python знак + расширяется, чтобы соответствовать одному или нескольким вхождениям регулярного выражения, предшествующим ему.В этом случае это \s, который расширяется от конца первого поля до следующего поля.

В качестве альтернативы, если входной файл не разделен табуляцией, вы можете извлечь значения поля с учетом поля фиксированной длины, а затем выполнитьa strip()

fields = [ (0,10),
           (10, 20),
           (20,36),
           (36,100) # Assuming last field will not cross this length
         ]
field_values = [ line[ x[0]:x[1] ].strip() for x in fields ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...