【问题标题】:Reading multiple files using pandas使用 pandas 读取多个文件
【发布时间】:2019-04-17 16:05:21
【问题描述】:

我想一次读取多个文件。我有两个文件中的数据,如下所示:

数据:

123.22.21.11,sid
112.112.11.1,john
110.11.23.23,jenny
122.23.21.13,ankit  

数据1:

145.123.11.1, Joaquin  

我根据this 链接尝试了几个答案。以下是我的代码:

df = pd.concat(map(pd.read_csv, glob.glob(os.path.join(" ", "/home/cloudera/Desktop/sample/*"))))  

当我运行这段代码时,它给我的输出如下:

>>> df
   123.22.21.11 145.123.11.1 Joaquin    sid
0  112.112.11.1          NaN     NaN    NaN
1  110.11.23.23          NaN     NaN    NaN
2  122.23.21.13          NaN     NaN    NaN
0  112.112.11.1          NaN     NaN   john
1  110.11.23.23          NaN     NaN  jenny
2  122.23.21.13          NaN     NaN  ankit

但是当我显示时,我需要输出如下和不同的列:

123.22.21.11,sid
112.112.11.1,john
110.11.23.23,jenny
122.23.21.13,ankit
145.123.11.1,Joaquin  

那我该怎么做呢??

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您的问题是 pd.read_csv() 默认需要列标题/名称。 Concat 使用这些来匹配。我可以使用"partial" 将kwarg names=None 传递到map

    import glob
    import os
    import pandas as pd
    from functools import partial
    mapfunc = partial(pd.read_csv, header=None)
    df = pd.concat(map(mapfunc, glob.glob(os.path.join(" ", "/home/cloudera/Desktop/sample/*"))))
    

    输出:

                  0         1
    0  123.22.21.11       sid
    1  112.112.11.1      john
    2  110.11.23.23     jenny
    3  122.23.21.13     ankit
    0  145.123.11.1   Joaquin
    

    您可以在此处查看部分信息: Using map() function with keyword arguments

    根据请求编辑:

    这不是很漂亮,但您可以遍历目录并使用可变的“计数器”一次处理“计数器”文件。

    # Initialize Variables
    fpath = "C:/Users/5188048/Desktop/example/"
    interval = 5
    filenames = []
    
    # loop through files in directory
    for i, j in enumerate(os.listdir(fpath)):
    
        # append filenames to list, initialized previously
        filenames.append(j)
    
        # for every interval'th file, perform this...
        if (i+1)%interval==0:
    
            # use first file to initialize dataframe
            temp_df = pd.read_csv(fpath+filenames[0], header=None)
    
            # loop through remaining files
            for file in filenames[1:]:
    
                # concatenate additional files to dataframe
                temp_df = pd.concat([temp_df, pd.read_csv(fpath+file, header=None)], ignore_index=True)
    
            # do your manipulation here, example reset column names
            temp_df.columns = ['IP_Address', 'Name']
    
            # Generate outfile variable name & path
            out_file = fpath+'out_file_' + str(int((i+1)/interval)) + '.csv'
    
            # write outfile to csv
            temp_df.to_csv(out_file, index=False)
    
            # reset variable
            filenames = []
    
        else:
    
            pass
    

    【讨论】:

    • 感谢您的回答。我还有几个问题。如何分配列名?如果数据本身存在标题,那么如何将这些标题分配为该数据的列名?因为在特定列上我必须应用正则表达式模式,最后我必须保存它
    • 如果文件中有标准的列,您可以在之后重命名这些列。我不会尝试在 1 行代码中做更多的事情。如果您要更改列名,我会将其分解为一个函数或一系列行,它们将读取单独的数据帧并在调整列名后将它们组合起来。
    • 是的,我知道该怎么做。在这里只需要一个帮助。您能否详细说明一个班轮代码。它有效,但只需要了解。
    • 我还有一个疑问,假设我有 10 个文件,其中我必须处理 5 个文件的数据,应用正则表达式,然后将其保存在一个文件中,同样我必须为其他 5 个文件执行此操作文件等等……那怎么办呢。如果你不介意你可以修改你的代码。只是想更有活力。无论如何,您的回答有所帮助,但只是试图探索不同的想法。我猜会涉及到一个 for 循环。
    • 您可以在 os.listdir() 中使用循环来遍历文件。您绝对不会在基于文件名的条件下单行执行此操作。不在最佳实践范围内。
    【解决方案2】:

    我认为将其拆分为几个步骤会更容易且更具可读性。您还想通过将 header=None 传递给 pd.read_csv 来明确告诉 pandas 没有标头。

    # Get list of files
    files = glob.glob(os.path.join(" ", "/home/cloudera/Desktop/sample/*"))
    # Read list of files into a list of dataframes
    df_list = [pd.read_csv(f, header = None) for f in files]
    # Stack all dataframes into one (you can change the parameters as you want)
    df = pd.concat(df_list, ignore_index = True, sort = False) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-03
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 2021-04-05
      • 2021-12-28
      • 1970-01-01
      • 2022-09-23
      相关资源
      最近更新 更多