Невозможно сместить значения из одного заголовка в другой - PullRequest
2 голосов
/ 03 октября 2019

Я пытаюсь поменять значения между двумя ячейками под заголовками Title и Name в CSV-файле на основе условия. Я получаю успех, когда заголовки имеют вид:

Organization Working since Gender Title Name ID

Однако, когда они похожи на следующие (multiple headers having the same set of names) Я застрял:

Organization Working since Gender Title Name ID Title Name ID

Что яя пытаюсь сделать, это проверить, содержит ли заголовок Title какое-либо значение, но Name не содержит. Если это так, то содержимое под заголовком Title будет смещено на Name. Однако, если содержимое под заголовком Name уже имеет какое-либо значение, оставьте их как есть.

Я пробовал (работает, когда есть один набор заголовков):

import csv

with open('profile_info.csv', 'r') as infile, open('modified.csv', 'w', newline="") as outfile:
    reader = csv.DictReader(infile)
    writer = csv.DictWriter(outfile, fieldnames=['Title','Name','ID'])
    writer.writeheader()
    for row in reader:
        if not row['Name']:
            row['Name'] = row['Title']

            """I don't know any better option for the following line"""

            row['Title']= ""
        else:
            row['Title'],row['Name']
        writer.writerow(row)
        print(row['Title'],row['Name'])

Изображение из profile_info.csv файла.

Изображение из modified.csv файла.

Если вы хотите проверить себя, это файл main csv дляваше удобство.

Ответы [ 2 ]

3 голосов
/ 05 октября 2019

Вы не можете использовать DictReader при наличии дублирующих заголовков. Что вы можете сделать, так это перейти к csv.reader, и у вас есть логика для присвоения значения.

Я считаю, что проще использовать pandas и numpy lot (если у вас есть свобода установки этих пакетов).

import pandas as pd
import numpy as np

df = pd.read_csv("profile.csv")

#handling the second 'Name' and 'Title' header
df['Name.2'] = np.where(df['Name.1'].isna(), df['Title.1'], df['Name.1'])
df['Title.1'] = np.where(df['Name.1'].isna(), "", df['Title.1'])

#handling the first 'Name' and 'Title' header
df['Name.3'] = np.where(df['Name'].isna(), df['Title'], df['Name'])
df['Title'] = np.where(df['Name'].isna(), "", df['Title'])

# Drop the old columns, since we have new ones in 'Name.2' and 'Name.3'
df.drop(['Name.1','Name'], inplace=True, axis=1)

# Rearranging the columns to match modified.csv
df = df[['Organization', 'Working since', 'Gender', 'Title', 'Name.3','ID','Title.1','ID.1','Name.2']]

# Rename columns to match modified.csv
df.rename(columns={'Name.2':'Name', 'Name.3': 'Name', 'Title.1':'Title', 'ID.1':'ID'}, inplace=True)
df.to_csv("modified.csv", index=False)

Панды могут идентифицировать дубликаты заголовков и добавлять к ним суффикс, облегчая изменение столбцов.

1 голос
/ 05 октября 2019

Это решение не требует специальных пакетов. Он просто читает первую строку файла CSV, переименовывает ошибочные столбцы и передает переименованные столбцы в вызов cvs.DictReader.

import csv

with open('profile_info.csv', 'r') as infile, open('modified.csv', 'w', newline="") as outfile:
    # read bad column names to get rid of it
    infile.readline()
    # new column names:
    column_names = ['Organization', 'Working since', 'Gender', 'Title', 'Name', 'ID', 'Title_1', 'Name_1', 'ID_1']
    reader = csv.DictReader(infile, fieldnames=column_names) # supply modified column names
    writer = csv.DictWriter(outfile, fieldnames=column_names)
    writer.writeheader()
    for row in reader:
        if not row['Name']:
            row['Name'] = row['Title']
            row['Title']= ""
        if not row['Name_1']:
            row['Name_1'] = row['Title_1']
            row['Title_1']= ""
        writer.writerow(row)
...