如何使用 pandas 从文件夹中读取和组合具有相似名称的 .csv 文件
Posted
技术标签:
【中文标题】如何使用 pandas 从文件夹中读取和组合具有相似名称的 .csv 文件【英文标题】:How to read and combine .csv files with similar names from a folder using pandas 【发布时间】:2021-10-09 19:49:38 【问题描述】:我在文件夹C/Downloads
中有如下文件名-
Mango001-003.csv
Mango004-006.csv
Mango007-100.csv
Applefruit.csv
Banana001-003.csv
Banana004-006.csv
如何分别导入水果文件,然后将相同的水果文件合并成一个文件?
预期的输出是 Mango 的一个输出,Apple 的一个输出和 Banana 的一个输出
import os
import re
data_files = os.listdir(r'C:\Downloads')
def load_files(filenames):
# Pre-compile regex for code readability
regex = re.compile(r'Mango.*?.csv')
# Map filenames to match objects, filter out not matching names
matches = [m for m in map(regex.match, filenames) if m is not None]
li = []
for match in matches:
df = pd.read_csv(match, index_col=None, header=0, dtype=object)
li.append(df)
#Concatenating the data
frame = pd.concat(li, axis=0, ignore_index=True)
return (frame)
df = load_files(data_files)
print(df.shape)
df.head(2)
我遇到了错误。另外,不可能这么复杂,一定是我做错了什么。
【问题讨论】:
【参考方案1】:我认为最简单的方法是使用glob.glob
获取以特定水果名称(这里我使用芒果)开头的所有文件的列表,然后使用pd.concat
将它们连接在一起。
data_files = r"path\to\folder\containing\csv"
df_mango= pd.DataFrame()
df_mango= pd.concat(map(pd.read_csv,glob.glob(os.path.join(data_files,'mango*.csv'))), ignore_index= True)
df_mango.to_csv('mango.csv')
这是我试过的例子:
mango0110.csv
A B C
0 1 2 3
mango01220.csv
A B C
0 4 5 6
To get:
A B C
0 1 2 3
1 4 5 6
【讨论】:
它完成了这项工作,但我无法插入分隔符 df = pd.read_csv(filename, sep=",") 为什么需要分隔符?我假设所有文件名都以水果的名称开头,并且 glob.glob(os.path.join(data_files,'mango*.csv') 获取以 mango 开头的文件,然后将它们全部连接起来 显然 * 说明了芒果后面的任何内容。如我的示例所示,如 mango0110.csv 等 假设我的文件中的值用“~!”分隔我想导入数据集 哇,这很有趣。到目前为止,我真的考虑过除逗号分隔值之外的任何东西(因为我在你的示例中只找到了 csv)。让我试试这种情况:)【参考方案2】:也许不是最好的方法,但是对于给定的文件名......
试试:
import pandas as pd
import glob
import re
path = r'./files' # use your path
all_files = glob.glob(path + "/*.csv")
fruits = []
# for all files in the folder get the fruit name
# this could be where things go wrong if the regex does not
# account for all filename types. Pattern may need tweaking
# example https://regex101.com/r/E69LWa/1
for file in all_files:
cleanFile = file.replace('fruit', '')
match = re.match(r'^.*/([A-Za-z]+)',cleanFile)
fruits.append(match.group(1))
# There will be one output for Mango, one for Apple & one for Banana hence three...
dfs_man = []
dfs_ban = []
dfs_app = []
# for all files create a df and append to the correct list holding other dfs of the same fruit
for i, file in enumerate(all_files):
df = pd.read_csv(file)
if fruits[i] == 'Mango':
dfs_man.append(df)
elif fruits[i] == 'Banana':
dfs_ban.append(df)
elif fruits[i] == 'Apple':
dfs_app.append(df)
# concatenate if more than one df in list, else just get the df out of list
if len(dfs_man) > 1:
df_mango = pd.concat(dfs_man, ignore_index=True)
elif len(dfs_man) == 1:
df_mango = dfs_man[0]
if len(dfs_ban) > 1:
df_banana = pd.concat(dfs_ban, ignore_index=True)
elif len(dfs_ban) == 1:
df_banana = dfs_ban[0]
if len(dfs_app) > 1:
df_apple = pd.concat(dfs_app, ignore_index=True)
elif len(dfs_app) == 1:
df_apple = dfs_app[0]
print(df_mango.shape, df_banana.shape, df_apple.shape)
【讨论】:
@VidyaGanesh 什么不安全?【参考方案3】:谢谢@Vidya Ganesh
data_files = r'C:\Downloads'
list_file_names = ['Mango','Apple','Banana']
for i in list_file_names:
name = i
df = pd.DataFrame()
df= pd.concat(map(pd.read_csv,glob.glob(os.path.join(data_files,str(name)+'*.csv'))), ignore_index= True)
df = df.loc[:1000,:]
print (name)
print (df.shape)
df.to_csv(str(name)+".csv")
【讨论】:
以上是关于如何使用 pandas 从文件夹中读取和组合具有相似名称的 .csv 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 pandas read_pickle 从 qrc 资源文件中读取包含 pandas 数据框的 pickle 文件?
如何从一个文件中读取多个 JSON 数据列表到 Pandas
如何使用 pandas 从 GitHub 读取 CSV 文件
从压缩文件夹中的文件夹中读取 txt 文件作为 pandas 数据框