Объединить несколько файлов CSV в один файл и добавить имя столбца каждого CSV в первом столбце - PullRequest
0 голосов
/ 16 ноября 2018

Привет всем, я пробую этот кусок кода, но я не получил желаемый результат, пожалуйста, помогите мне для получения правильного результата.

import os
import glob   
import pandas as pd


path = r'filespath'

all_files = glob.glob(os.path.join(path, "*.csv"))

names = [os.path.basename(x) for x in glob.glob(path+'\*.csv')]

df = pd.DataFrame()

for file_ in all_files:
    file_df = pd.read_csv(file_,sep=';', parse_dates=[0], infer_datetime_format=True,header=None )
    file_df['file_name'] = file_
    df = df.append(file_df)
    print(df)

Я хочу добавить несколько CSV-файлов в один CSV-файл и добавить имя CSV-файла в первый столбец, если у кого-нибудь есть идея, поделитесь .thanks

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Я предлагаю вам создать функцию для чтения и добавить имя файла, после чего вы можете просмотреть all_files

import pandas as pd
import numpy as np
import os
import glob

path = 'folder'
if not os.path.exists(path):
    os.makedirs(path)


def fun(fn):
    df = pd.read_csv(fn)
    # edit so file_name is the first col
    cols = df.columns.tolist()
    cols = ["file_name"] + cols
    # end edit
    df["file_name"] = fn
    return df[cols]

N = 100
for i in range(10):
    df = pd.DataFrame(np.arange(i*N, (i+1)*N))
    df.to_csv("{}/file_{:02}.csv".format(path, i), index=False)

all_files = sorted(glob.glob(os.path.join(path, "*.csv")))

dfs = [fun(fn) for fn in all_files]
df = pd.concat(dfs, ignore_index=True)
df.to_csv("single_file.csv", index=False)
0 голосов
/ 16 ноября 2018

Я не могу полностью понять проблему, с которой вы сталкиваетесь, если вы не предоставите структуру используемых вами csvs и полученный результат.

Можете ли вы привести небольшой пример CSV-файлов и нежелательный результат, чтобы мы могли понять, в чем проблема?

Чтобы привести небольшой пример, вы можете использовать df.head(2) для двух образцов CSV-файлов.

Обновление

Предлагаемое решение

Вот рабочий пример, предоставленный примером, приведенным здесь

Образец, который я использовал:

df1 = pd.DataFrame(np.asarray([[1, 1], [2, 2]]), columns=['A', 'B'])
df2 = pd.DataFrame(np.asarray([[3, 3], [4, 4]]), columns=['A', 'B'])
df3 = pd.DataFrame(np.asarray([[5, 5], [6, 6]]), columns=['A', 'B'])
df1.to_csv('1.csv')
df2.to_csv('2.csv')
df3.to_csv('3.csv')

Полученные csvs:

   A  B
0  1  1
1  2  2

   A  B
0  3  3
1  4  4

   A  B
0  5  5
1  6  6

Код конкатенации:

import os
import glob
import pandas as pd

path = r'.'
all_files = glob.glob(os.path.join(path, "*.csv"))
names = [os.path.basename(x) for x in glob.glob(path+'\*.csv')]
df = pd.DataFrame()

for file_ in all_files:
    file_df = pd.read_csv(file_, index_col=0, header=0)
    file_df['file_name'] = file_
    df = df.append(file_df)
print(df)

Результат конкатенации:

   A  B file_name
0  5  5   ./3.csv
1  6  6   ./3.csv
0  1  1   ./1.csv
1  2  2   ./1.csv
0  3  3   ./2.csv
1  4  4   ./2.csv

Обратите внимание , что есть два отличия от вашего кода:

  1. Параметр заголовка установлен на 0 вместо Нет .
  2. Параметр index_col установлен на 0 вместо 'Нет'.

Объяснение

Я думаю, что проблемы, с которыми вы столкнулись, связаны с этими параметрами, поэтому я объясню их использование.

Допустим, у вас есть следующий CSV-файл:

,A,B
0,1,1
1,2,2

Обратите внимание, что первая строка - это заголовок, а первая строка - это индекс.

Если использовать функцию pandas.read_csv(...), они получат следующий результат:

   Unnamed: 0  A  B
0           0  1  1
1           1  2  2

Это означает, что панды взяли первый столбец, который является столбцом индекса, и обработали его как обычный столбец данных. Чтобы избежать этого, можно установить для параметра index_col значение 0.
Таким образом, панды будут знать, что нужно проанализировать этот столбец как индекс. Таким образом, результат pandas.read_csv(..., index_col=0) приведет к следующему:

   A  B
0  1  1
1  2  2

Теперь, если кто-то читает несколько CSV-файлов с использованием этого метода, их объединение приведет к желаемому виду, который не включает их прежний индекс, как было показано в приведенном мною примере.

Кроме того, если бы я установил для параметра header значение None, вся первая строка считалась бы данными, и мы получили бы следующий нежелательный результат:

     0  1  2
0  NaN  A  B
1  0.0  1  1
2  1.0  2  2

Это также может привести к нежелательному результату в объединенном кадре данных.

Обновление 2

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

Причина этой проблемы в том, что в строке file_df['file_name'] = file_.
Вы использовали file_ , который перебирает all_files .
И действительно, all_files содержит путь к вашим файлам csv.
Вы сохранили базовые имена своих файлов в переменной names , поэтому, чтобы получить только базовые имена файлов CSV в новом столбце, я предлагаю следующие изменения в код, представленный выше:

path = r'.'
all_files = glob.glob(os.path.join(path, "*.csv"))
names = [os.path.basename(x) for x in all_files]
df = pd.DataFrame()

for file_, name in zip(all_files, names):
    file_df = pd.read_csv(file_, index_col=0)
    file_df['file_name'] = name
    df = df.append(file_df)
print(df)

Изменения, которые я сделал:

  1. Исправлен разбор базовых имен names = [os.path.basename(x) for x in all_files]
  2. Использовали базовые имена в новом столбце file_df['file_name'] = name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...