读入并合并或合并多个文件到公共ID列上的一个数据帧中



我正在尝试连接一个目录中的多个文件。我可以连接文件,但是我得到了重复的行和列。如果输入文件中不存在字段,那么输出文件最好显示NaN或null。

理想情况下,输出如下:

合并的.csv

ItemID  Price  Discount ItemName          Desc  Barcode
0       1      4       2.0      Toy      For kids   667865
1       2     10       1.0     Game    For adults   998364
2       3      8       NaN      NaN  For everyone    43831

file1.csv

ItemID  Price  Discount
0       1      4       2.0
1       2     10       1.0
2       3      8       NaN

file2.csv

ItemID ItemName          Desc
0       1      Toy      For kids
1       2     Game    For adults
2       3      NaN  For everyone

文件3.CSV

ItemID  Barcode
0       1   667865
1       2   998364
2       3    43831

以下是我正在处理的代码:

import glob , os
import pandas as pd
path = '/location/test/'
all_files = glob.glob(os.path.join(path, "*.csv"))
pd.concat([pd.read_csv(f, sep=';').assign(file=os.path.basename(f)) for f in all_files]).to_csv('merged.csv', index=False)
  1. 您可以将axis=1传递给pd.concat,并使用.set_index('ItemID')以便在ItemID上使用concat。你最后只需要reset_index()
  2. 您可以使用mergefunctools获取reduce

我更喜欢前者,因为它有点干净,但我将包括reduce解决方案,以防它更具性能,或者如果您想使用.merge:独有的一些附加功能

设置:

import glob , os
import pandas as pd
from functools import reduce
path = '/location/test/'
all_files = glob.glob(os.path.join(path, "*.csv"))

方法1*(请参阅答案末尾关于该方法的注释(:

(pd.concat([pd.read_csv(f, sep=';').set_index('ItemID') for f in all_files], axis=1)
.reset_index().to_csv('merged.csv', index=False))

方法2:

(reduce(lambda  left,right: pd.merge(left,right,on=['ItemID'], how='left'),
[pd.read_csv(f, sep=';') for f in all_files]).to_csv('merged.csv', index=False))

.csv文件中的输出如下所示:

Out[1]:
ItemID  Price  Discount ItemName          Desc  Barcode
0       1      4       2.0      Toy      For kids   667865
1       2     10       1.0     Game    For adults   998364
2       3      8       NaN      NaN  For everyone    43831

对于方法#1,这不是一个通用的解决方案,只是因为用于连接数据的同一列存在于所有数据帧中。例如,如果您有一个具有非唯一值的基文件,而您正试图将具有唯一值的其他数据连接到该基文件,则其他文件将连接在一起,但该基文件不会连接到其他文件,并且您将收到一个ValueError。下面,我首先阅读了基本文件。然后我concat除基本文件外的所有其他文件。然后,我使用join将基本文件和其他文件连接在一起,但如果密钥中存在非唯一值,则pd.concat将不起作用,因此最好使用joinmerge:

import pandas as pd
import glob , os
path = 'Downloads\'
base_file = os.path.join(path, "EVS1CPP.csv")
all_files = glob.glob(os.path.join(path, "*1CPP.csv"))
all_files.remove(base_file)
df_base = pd.read_csv(base_file, sep=';').set_index('ARTICLE_ID')
dfs = pd.concat([pd.read_csv(f, sep=';').set_index('ARTICLE_ID') for f in all_files], axis=1)
df = df_base.join(dfs, how='outer').rename_axis('ARTICLE_ID').reset_index()
df

最新更新