Как перенести общие столбцы между двумя файлами CSV

Я новичок в программировании и хочу написать эту программу, которая передает общие столбцы между file1.csv и file2.csv.

Ввод:

file1.csv выглядит так:

ID,Nickname,Gender,SubjectPrefix,SubjectFirstName,Whatever1A,Whaterver2A,SubjectLastName
1,J.,M,Dr.,Jason,,,Allan
2,B.,M,Mr.,Brian,,,Welch

file2.csv выглядит так:

nickname,gender,city,id,prefix_name,first_name,Whatever1B,last_name,Whatever2B,Whatever3B,Whatever4B

Проблема:

Как сравнить заголовок file1.csv и file1.csv, чтобы определить, а затем перенести между ними «общие» столбцы. «Общие» столбцы — это столбцы с похожими соглашениями об именах (например, ID и id , Nickname и nickname) или те, которые не обязательно имеют одинаковые соглашения об именах, но хранят одинаковые данные (например, SubjectPrefix и prefix_name , SubjectFirstName и first_name).

Вывод:

Вывод должен быть таким.

  • Примечание. переданные столбцы "id", "nickname" и "gender" имеют одинаковые названия между заголовками file1.csv и file2.csv. А столбцы "prefix_name" и "first_name" соответствуют "SubjectPrefix" и "SubjectFirstName" соответственно.

    id,nickname,gender,prefix_name,first_name,last_name  
    1,J.,M,Dr.,Jason,Allan
    2,B.,M,Mr.,Brian,Welch
    

Я пробовал этот код:

import csv
import collections

csv_file1 = "file1.csv"
csv_file2 = "file2.csv"

data1 = list(csv.reader(file(csv_file1,'r')))
data2 = list(csv.reader(file(csv_file2,'r')))

file1_header = data1[0][:] #get the header from file1
file2_header = data2[0][:] #get the header from file2
lowered_file1_header = [item.lower() for item in file1_header] #lowercase file1 header
lowered_file2_header = [item.lower() for item in file2_header] #lowercase file2 header anyways
col_index_dict = {}

for column in lowered_file1_header:
    if column == "subjectprefix":  # identify "subjectprefix" column in file1.csv
        col_index_dict[column] = lowered_file1_header.index(column)

   elif column == "subjectfirstname": # identify "subjectfirstname" column in file1.csv
        col_index_dict[column] = lowered_file1_header.index(column)

   elif column in file2_header: # identify the columns with same naming
        col_index_dict[column] = lowered_file1_header.index(column)

   else:
        col_index_dict[column] = -1 # mark the not matching columns

# Build header
output = [col_index_dict.keys()]
is_header = True

for row in data1:
    if is_header is False:
        rowData = []
        for column in col_index_dict:
            column_index = col_index_dict[column]
            if column_index != -1:
                rowData.append(row[column_index])
            else:
                rowData.append('')
        output.append(rowData)
    else:
        is_header = False

print(output)

Любая идея, как решить эту проблему?


person MEhsan    schedule 03.07.2016    source источник


Ответы (2)


Добро пожаловать в программирование. Позвольте представить вам удивительную библиотеку pandas.

С моей головы, вот что-то, что решит вашу проблему. (Я не говорю, что это эффективно! Так что для больших наборов данных это может быть проблемой)

import pandas as pd

df = pd.read_csv('file1.csv')
df2 = pd.read_Csv('file2.csv')

df_columns = set(list(df.columns))
df2_columns = set(list(df2.columns))

common_columns = list(df_columns.intersection(df2_columns))

common_df = df[common_columns]
common_df2 = df2[common_colmns]

## At this point you have the common columns for both CSV's. if you want
## to make them into one, just use df concatenate / append. else, you can save both of them like this:

common_df.to_csv('common1.csv')
common_df2.to_csv('common2.csv')
person Wboy    schedule 03.07.2016

Спасибо Wboy за ваш вклад, ваш вклад был действительно полезен.

Мне удалось найти решение проблемы с помощью библиотеки Pandas. Вот код:

import pandas as pd

# read the csv files
df = pd.read_csv('file1.csv')
df2 = pd.read_csv('file2.csv')

# lowercase the headers
df.columns = df.columns.str.lower()
df2.columns = df2.columns.str.lower()

df_columns = set(list(df.columns))
df2_columns = set(list(df2.columns))

Определите и перенесите "общие" столбцы:

for col in list(df_columns):
    for col2 in list(df2_columns):
        if col == "subjectprefix" and col2 =="prefix_name":
            # copy the data from df["subjectprefix"] column to df2["prefix_name"] column in df2 dataframe
            df2["prefix_name"] = df['subjectprefix']
            df3 = [col2]
        elif col == "subjectfirstname" and col2 =="first_name":
            # copy the data from "subjectfirstname" column to "first_name" column
            df2["first_name"] = df["subjectfirstname"]
            df3.append(col2)

        elif col =="subjectlastname" and col2 =="last_name":
            #copy the data from "subjectfirstname" column to "last_name" column
            df2["last_name"] = df["subjectlastname"]
            df3.append(col2)

        elif col == col2:
            # copy the exactly matching to df2
            df2[col2] = df[col]
            df3.append(col2)

Удалите "необычные" столбцы из кадра данных df2:

for col2 in list(df2_columns):
if not col2 in df3:
    del df2[col2]

# print the output
df2.set_index("id",inplace=True)
print df2

Сохраните результат как файл .csv :

df2.to_csv('output.csv')

Я уверен, что это не оптимальное решение, и я надеюсь, что код можно было бы улучшить с точки зрения определения и передачи «общих» столбцов. Мой код полон операторов if/elif, и я уверен, что здесь должен быть лучший подход для реализации.

person MEhsan    schedule 03.07.2016
comment
Здесь просмотрите это для идей... set(list(x) не нужен... узнайте о фильтрации панд с помощью isin. people.duke.edu/~ccc14/sta-663/ - person Merlin; 04.07.2016