Как заполнить нулевые значения в столбце? - PullRequest
0 голосов
/ 04 мая 2020

Мне нужно прочитать CSV-файл и заполнить пустые / пустые значения в столбце «Телефон, электронная почта, адрес, город, штат, почтовый индекс» на основе типа отношения и LastName и записать в новый CSV-файл. Пример: если для атрибута personType используется значение «Работодатель» и его иждивенцы имеют одинаковую фамилию, а если у иждивенцев отсутствует «Телефон, электронная почта, адрес, город, штат, почтовый индекс», я должен заполнить нулевые значения с помощью «Телефон, электронная почта работодателя» , адрес, город, штат, почтовый индекс». Есть две основные проблемы, с которыми я сталкиваюсь: 1) LastName может быть одинаковым для разных людей / семей (т. Е. Строки 5-10), поэтому l oop должен прерываться и продолжаться всякий раз, когда «Relationship» меняется на «Employer» 2) В некоторых случаях зависимая фамилия не будет такой же, как фамилия работодателя, но все же мы должны заполнить нулевые значения, если она попадает между теми же фамилиями (т. Е. Строка 8).

Я не буду возможность использовать python pandas, так как остальная часть кода / программ основана исключительно на python 2.7.

Формат ввода / таблица выглядят как показано ниже с пустыми ячейками (CSV-файл):

[FirstName  LastName    DoB Relationship    Phone   Email   Address City    State   Zip
Hannah  Kahnw   9/12/1972   Employer    1457871452  hann@gmail.com  Han Ave hannas  UT  563425
Michel  Kahnw   2/9/1993    Dependent                       
Jonaas  Kahnw   2/22/1997   Dependent                       
Mikkel  Nielsen 1/25/1976   Employer    4509213887  mik@yah.com 887 Street  neil    NY  72356
Magnus  Nielsen 9/20/1990   Dependent                       
Ulrich  Nielsen 9/12/1983   Employer    7901234516  ulric@mail.com  Ulric Build mavric  KS  421256
kathari Nielsen 10/2/2003   Dependent                       
kathy   storm   12/12/1999  Dependent                       
kiiten  Nielsen 6/21/1999   Dependent                       
Elisab  Doppler 2/22/1987   Employer    5439001211  elop@amaz.com   Elisa apart Elis    AR  758475
Peterp  Doppler 1/25/1977   Employer    6847523758  per@dail.com    park Ave    Pete    PT  415253
bartos  Doppler 9/21/1990   Dependent][1]                       

Формат вывода должен быть таким, как показано ниже:

FirstName   LastName    DoB Relationship    Phone   Email   Address City    State   Zip
Hannah  Kahnw   9/12/1972   Employer    1457871452  hann@gmail.com  Han Ave hannas  UT  563425
Michel  Kahnw   2/9/1993    Dependent   1457871453  hann@gmail.com  Han Ave hannas  UT  563426
Jonaas  Kahnw   2/22/1997   Dependent   1457871454  hann@gmail.com  Han Ave hannas  UT  563427
Mikkel  Nielsen 1/25/1976   Employer    4509213887  mik@yah.com 887 Street  neil    NY  72356
Magnus  Nielsen 9/20/1990   Dependent   4509213888  mik@yah.com 888 Street  neil    NY  72357
Ulrich  Nielsen 9/12/1983   Employer    7901234516  ulric@mail.com  Ulric Build mavric  KS  421256
kathari Nielsen 10/2/2003   Dependent   7901234517  ulric@mail.com  Ulric Build mavric  KS  421257
kathy   storm   12/12/1999  Dependent   7901234518  ulric@mail.com  Ulric Build mavric  KS  421258
kiiten  Nielsen 6/21/1999   Dependent   7901234519  ulric@mail.com  Ulric Build mavric  KS  421259
Elisab  Doppler 2/22/1987   Employer    5439001211  elop@amaz.com   Elisa apart Elis    AR  758475
Peterp  Doppler 1/25/1977   Employer    6847523758  per@dail.com    park Ave    Pete    PT  415253
bartos  Doppler 9/21/1990   Dependent   6847523759  per@dail.com    park Ave    Pete    PT  415254


import csv
from collections import namedtuple


def get_info(file_path):

    # Read data from file and convert to list of namedtuples
    # dictionary to use to fill in missing information from others.
    with open(file_path, 'rb') as fin:
        csv_reader =  csv.reader(fin, skipinitialspace=True)

        header = next(csv_reader)
        Record = namedtuple('Record', header)

        addr_dict = {}
        data = [header]

        for rec in (Record._make(row) for row in csv_reader):
            if rec.Email or rec.Phone or rec.Address or rec.City or rec.State or rec.Zip:
                addr_dict.setdefault(rec.LastName, []).append(rec)  # Remember it.

    # Try to fill in missing data from any other records with same Address.
    for i, row in enumerate(data[1:], 1):
        if not (row.Phone and row.Email and rec.Address and rec.City and rec.State and rec.Zip):  # Info missing?
            # Try to copy it from others at same address.
            updated = False
            for other in addr_dict.get(row.LastName, []):
                if not row.Phone and other.Phone:
                    row = row._replace(Phone=other.Phone)
                    updated = True
                if not row.Email and other.Email:
                    row = row._replace(Email=other.Email)
                    updated = True
                if not row.Address and other.Address:
                    row = row._replace(Address=other.Address)
                    updated = True
                if not row.City and other.City:
                    row = row._replace(City=other.City)
                    updated = True
                if not row.Zip and other.Zip:
                    row = row._replace(Zip=other.Zip)
                    updated = True
                if row.Phone and row.Email and rec.Address and rec.City and rec.State and rec.Zip:  # Info now filled in?
                    break

            if updated:
                data[i] = row

    return data


INPUT_FILE = 'null_cols.csv'
OUTPUT_FILE = 'fill_cols.csv'

data = get_info(INPUT_FILE)

with open(OUTPUT_FILE, 'wb') as fout:
    writer = csv.DictWriter(fout, data[0])  # First elem has column names.
    writer.writeheader()
    for row in data[1:]:
        writer.writerow(row._asdict())

#(i got this code from earlier question which i asked in S.O This script doesn't include relationshiptype logic and also it doesn't consider the Duplicate LastName issue)

Спасибо за помощь !!

1 Ответ

0 голосов
/ 04 мая 2020

ОК, есть простой способ сделать это, используя ffill, как показано ниже, , однако, это будет работать, только если иждивенцы всегда следуют за своим работодателем в порядке строк , что имеет место в выборке данных, которую вы ' при условии, что приведенный ниже код работает:

import pandas as pd

#read in your csv file
df = pd.read_csv('fileName.csv')


#loop over columns and replace nans with the most recent value available
for c in df.columns:
    df[c].fillna(method='ffill', inplace=True)

#write out your df back to csv
df.to_csv('newFile.csv', index=False)
...