我正在尝试连接一个目录中的多个文件。我可以连接文件,但是我得到了重复的行和列。如果输入文件中不存在字段,那么输出文件最好显示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)
- 您可以将
axis=1
传递给pd.concat
,并使用.set_index('ItemID')
以便在ItemID
上使用concat
。你最后只需要reset_index()
- 您可以使用
merge
从functools
获取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将不起作用,因此最好使用join
或merge
:
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