首页 > 解决方案 > 合并或连接具有不同列数的多个 CSV 文件并分配文件名列

问题描述

嗨,我是 python pandas 的新手,我是使用数据框编写代码的新手。因此,我从 Internet 获得了有关如何将文件夹中的两个或多个 csv 文件合并到一个常见 csv 文件的代码。但我无法获得一行代码,我不知道该怎么做。任何人都可以帮助我吗?

import os, glob
import pandas as pd

path = "/home/user/data/"

all_files = glob.glob(os.path.join(path, "data_*.csv"))
df_merged   = pd.concat(df_from_each_file, ignore_index=True)
df_merged = (pd.read_csv(f, sep=',') for f in all_files)
df_merged.to_csv( "merged.csv")

所以在这里我尝试了一切,但无法获得 df_from_each_file 。所以任何人都可以帮助我,我希望输出是这样的

所以这就是我的输出应该是什么样子

标签: pythonpandascsv

解决方案


编辑#2:实际数据与样本数据不同,需要水平连接而不是垂直连接axis=1。这会创建重复的列,因此需要转置数据框.T,以便将这些重复的列作为重复行删除drop_duplicates()。最后,它需要再次转置回来.T。此外,我们在读取文件时必须排除听众,因为其中两个文件具有完全相同的值,因此它们会被无意中删除。这就是为什么我们必须将列标题作为值读取,然后在最后将它们提升回标题并删除第一行.iloc

pd.concat([pd.read_csv(f, header=None) for f in all_files], axis=1).T.drop_duplicates().T.to_csv('merged.csv', index=False)
df.columns = df.iloc[0]
df = df.iloc[1:]
df.to_csv('merged.csv', index=False)

编辑#1:正如LinkedIn所讨论的,你的所有数据都在一个列中,所以为了将它作为多列读取,你需要使用sep='\s+',因为有多个空格分隔你的数据,所以你可以\s+用作分隔符或分隔符。

对于单线,.assign使用file=os.path.basename(f)

pd.concat([pd.read_csv(f, sep='\s+').assign(file=os.path.basename(f)) for f in all_files]).to_csv('merged.csv', index=False)

根据您的评论,我用不同的列测试了这个确切的代码并获得了成功的结果:

import pandas as pd
import glob, os
path = 'Desktop'
all_files = glob.glob(os.path.join(path, "Book*.csv"))
pd.concat([pd.read_csv(f, sep='\s+').assign(file=os.path.basename(f)) for f in all_files]).to_csv('merged.csv', index=False)

如果 excel 文件已经分列,则删除sep='\s+'并使用以下代码:

pd.concat([pd.read_csv(f).assign(file=os.path.basename(f)) for f in all_files]).to_csv('merged.csv', index=False)

Book1.csv

col1    col2    col3    col4    col5
1       2       3       4       5

Book2.csv

col1    col2    col3    col4
2       3       4       5

合并的.csv

col1    col2    col3    col4    col5    file
1       2       3       4       5       Book1.csv
2       3       4       5               Book2.csv

推荐阅读