将多个CSV文件导入Pandas并将它们合并成一个DataFrame

3

有多个csv文件(每个文件包含N行(例如1000行)和43列)。

想要从文件夹中读取几个csv文件到pandas中,并将它们合并成一个DataFrame。

但是,我还没有找出解决方法。

问题在于,DataFrame的最终输出(即frame = pd.concat(li, axis=0, ignore_index=True))将所有列(即43列)合并为一列(请参见附图) 代码截图

所选行和列的示例(文件一)

               Client_ID    Client_Name  Pointer_of_Bins   Date        Weight
                C0000001       POLYGONE      TI006093     12/03/2019   0.5
                C0000001       POLYGONE      TI006093     12/03/2019   0.6
                C0000001       POLYGONE      TI006093     12/03/2019   1.4
                C0000001       POLYGONE      TI006897     14/03/2019   2.9

选定行和列的一个示例(第二个文件) 客户端ID 客户端名称 Bin指针 日期 重量 C0000001 POLYGONE TI006093 22/04/2019 1.5 C0000001 ALDI TI006098 22/04/2019 0.7 C0000001 ALDI TI006098 22/04/2019 2.4 C0000001 ALDI TI006898 24/04/2019 1.9

预期输出如下所示(合并多个可能包含成千上万行和数十列的文件,附带的数据只是一个示例,实际的CSV文件可能在每个文件中包含数千行和超过45列的行)

               Client_ID    Client_Name  Pointer_of_Bins   Date        Weight
                C0000001       POLYGONE      TI006093     12/03/2019   0.5
                C0000001       POLYGONE      TI006093     12/03/2019   0.6
                C0000001       POLYGONE      TI006093     12/03/2019   1.4
                C0000001       POLYGONE      TI006897     14/03/2019   2.9   
                C0000001       POLYGONE      TI006093     22/04/2019   1.5
                C0000001       ALDI          TI006098     22/04/2019   0.7
                C0000001       ALDI          TI006098     22/04/2019   2.4
                C0000001       ALDI          TI006898     24/04/2019   1.9                                                             

点击此处下载两个CSV文件(虚拟数据)

到目前为止,我已经完成了以下工作:

import pandas as pd
import glob
path = r'C:\Users\alnaffakh\Desktop\doc\Data\data2\Test'
all_files = glob.glob(path + "/*.csv")
li = []
for filename in all_files:
    df = pd.read_csv(filename, sep='delimiter', index_col=None, header=0)
  # df = pd.read_csv(filename, sep='\t', index_col=None, header=0)
    li.append(df)
frame = pd.concat(li, axis=0, ignore_index=True)


去掉 sep='分隔符'。现在的代码会将所有数据框读取为一列。 - Quang Hoang
1
@QuangHoang,感谢您的回复,但是如果我将其删除,我会得到以下错误(UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc7 in position 8: invalid continuation byte)。 - Wisam hasan
请分享一些虚拟数据。我支持@QuangHoang所提到的:您需要删除sep ='delimiter'或使用文件中已使用的实际分隔符。这就是为什么我建议您分享一些虚拟数据(可能只有5列的4行),以便我们可以针对其进行测试。 - CypherX
你可以考虑使用dask。 - rpanai
1个回答

1

解决方案

您可以使用 pandas.concat 递归拼接 .csv 文件内容。
事实上,我看到您已经使用了它,您对 concat 的应用似乎很好。尝试查看您读取的各个数据帧。如果您没有提到正确的分隔符,那么您的列合并为单个列的唯一方法是。

import pandas as pd

dfs = list()
for filename in filesnames:    
    df = pd.read_csv(filename)    
    dfs.append(df)
frame = pd.concat(dfs, axis=0, ignore_index=True)
df.head()

使用虚拟数据的示例

由于现有的虚拟数据尚未以文本格式提供,因此我只使用了一些我自己制作的虚拟数据。

import pandas as pd
from io import StringIO # needed for string to dataframe conversion

file1 = """
Col1    Col2    Col3    Col4    Col5
1   ABCDE   AE10    CD11    BC101F
2   GHJKL   GL20    JK22    HJ202M
3   MNPKU   MU30    PK33    NP303V
4   OPGHD   OD40    GH44    PG404E
5   BHZKL   BL50    ZK55    HZ505M
"""

file2 = """
Col1    Col2    Col3    Col4    Col5
1   AZYDE   AE10    CD11    BC100F
2   GUFKL   GL24    JK22    HJ207M
3   MHPRU   MU77    PK39    NP309V
4   OPGBB   OE90    GH41    PG405N
5   BHTGK   BL70    ZK53    HZ508Z
"""

将数据作为单独的数据框加载,然后将它们连接起来。
df1 = pd.read_csv(StringIO(file1), sep='\t')
df2 = pd.read_csv(StringIO(file2), sep='\t')
print(pd.concat([df1, df2], ignore_index=True))

输出:

   Col1   Col2  Col3  Col4    Col5
0     1  ABCDE  AE10  CD11  BC101F
1     2  GHJKL  GL20  JK22  HJ202M
2     3  MNPKU  MU30  PK33  NP303V
3     4  OPGHD  OD40  GH44  PG404E
4     5  BHZKL  BL50  ZK55  HZ505M
5     1  AZYDE  AE10  CD11  BC100F
6     2  GUFKL  GL24  JK22  HJ207M
7     3  MHPRU  MU77  PK39  NP309V
8     4  OPGBB  OE90  GH41  PG405N
9     5  BHTGK  BL70  ZK53  HZ508Z

@Wisamhasan 感谢您提供数据。但是,请将两个csv文件的前5列和4行粘贴到问题陈述中作为样本数据。然后还要提供您的期望结果。您的数据需要尽可能简洁且可重现。最好不要共享数据文件。 - CypherX
@Wisamhasan 谢谢你提供的行和列信息。但是,我要求将数据作为文本粘贴到问题描述中。这样可以更容易地复制你的问题。请创建一个代码块,并将文件1和文件2中的数据列(子集)粘贴到该代码块中。 - CypherX
你使用的分隔符是什么? - CypherX
@Wisamhasan,您能否考虑**接受点赞**这个答案呢? - CypherX
1
@Meet 是的,您可以使用多索引与文件源标识符。但我建议不要将文件名作为多索引的一部分。文件名可能很长,并且当它们被命名时,您可能无法控制它们的命名逻辑。相反,如果您只想跟踪数据的来源,我建议您添加另一列“来源”,并在那里填写文件名。您始终可以通过条件提取特定于文件的数据来实现此目的。但是请考虑尽可能保持您的索引单数,除非绝对必要。 - CypherX
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接