首页 > 解决方案 > 使用逗号分隔符将带有列表的列拆分为单独的列,而不指定列名

问题描述

我想将下面的每个字段拆分为单独的列,并且我想在不指定列名的情况下执行此操作,因为我正在处理大量文件,一个接一个,并且每个文件都有不同的列数。目标是将每个文件读入数据帧,其文件名作为数据帧名称。我正在使用相同的字典:

在此处输入图像描述

import pandas as pd
import zipfile
import re

Tables = {}

with zipfile.ZipFile('*.zip') as z:
    for filename in z.namelist():
        df_name = filename.split(".")[1]
        if df_name == 'hp':
            with (z.open(filename)) as f:
                content = f.read().decode('utf-8')
                content = NewLineCorrection(content)
                df= pd.DataFrame(content)
                cols = list(df[0][0])
                df[0] = list(map(lambda el:[el], df[0]))
                #df[0] = df[0].split(',')
                print(df.head())
                #df.columns = df.iloc[0]
                #df = df.drop(index=0).reset_index(drop=True)
                #Tables[df_name] = df

def NewLineCorrection(content):
    corrected_content = ( re.sub(r'"[^"]*"', 
                             lambda x: 
                                 re.sub(r'[\r\n\x0B\x0C\u0085\u2028\u2029]', 
                                        '', 
                                        x.group()), 
                             content) )
    corrected_content = corrected_content.replace('"', '')
    corrected_content = corrected_content.replace('||@@##', ',')

    ContentList = list(corrected_content.splitlines())
    return ContentList

.split() 函数由于某种原因对我不起作用,我不知道如何找出原因。

标签: pythonpandasdataframecsv

解决方案


这可能不是最有效的方法,但它很灵活,因为您可以将 pandas read_csv 阅读器用于 csv 文件。例如,您可以通过这种方式自动解析 csv 文件中的日期/时间。

在下面的示例中,我假设有两个包含内容的 csv 文件

$ cat csv_with_brackets1.csv
[col1, col2, col3, col4]
[1, 14, 2015-12-02 17:02:32, 2, 1 ]
[2, 14, 2016-12-02 17:02:32, 4, 3 ]
[3, 14, 2018-12-02 17:02:32, 8, 4 ]
[4, 14, 2019-12-02 17:02:32, 9, 2 ]

$ cat csv_with_brackets2.csv
[othercol1, othercol2, othercol3, othercol4]
[1, 16, 2005-12-02 13:02:32, 3, 1 ]
[2, 16, 2006-12-02 13:02:32, 9, 3 ]
[3, 16, 2008-12-02 13:02:32, 8, 4 ]
[4, 16, 2009-12-02 13:02:32, 1, 2 ]

主要问题是您的行以 [ 开头并以 ] 字符结尾,这不是标准的。在“read_csv_with_brackets”下面的函数中,您首先通过创建一个干净的临时 csv 文件来删除括号,然后使用 pandas 中的 read_csv 函数来实际读取数据。

import re
from glob import glob
from pathlib import Path

import pandas as pd


def read_csv_with_brackets(filename):
    print(f"reading {filename}")
    tmp_file = "tmp_csv.txt"
    with open(filename, "r") as in_stream, open(tmp_file, "w") as out_stream:
        for line in in_stream.readlines():
            clean_line = re.sub("^\[|\]$", "", line.strip()) + "\n"
            out_stream.write(clean_line)
    data_df = pd.read_csv(tmp_file, parse_dates=True)
    Path(tmp_file).unlink()

    return data_df


file_collection = dict()
for file_name in glob("*.csv"):
    file_base = Path(file_name).stem
    df = read_csv_with_brackets(filename=file_name)
    file_collection[file_base] = df

for file_name, df in file_collection.items():
    print(f"Contents file {file_name}")
    print(df)

这种方法的缺点是您必须读取每个数据文件两次。但好处是您可以处理无效列,因为 read_csv 非常健壮。

脚本的输出如下所示

Contents file csv_with_brackets1
   col1                  col2   col3   col4
1    14   2015-12-02 17:02:32      2      1
2    14   2016-12-02 17:02:32      4      3
3    14   2018-12-02 17:02:32      8      4
4    14   2019-12-02 17:02:32      9      2
Contents file csv_with_brackets2
   othercol1             othercol2   othercol3   othercol4
1         16   2005-12-02 13:02:32           3           1
2         16   2006-12-02 13:02:32           9           3
3         16   2008-12-02 13:02:32           8           4
4         16   2009-12-02 13:02:32           1           2

推荐阅读