python - 使用逗号分隔符将带有列表的列拆分为单独的列,而不指定列名
问题描述
我想将下面的每个字段拆分为单独的列,并且我想在不指定列名的情况下执行此操作,因为我正在处理大量文件,一个接一个,并且每个文件都有不同的列数。目标是将每个文件读入数据帧,其文件名作为数据帧名称。我正在使用相同的字典:
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() 函数由于某种原因对我不起作用,我不知道如何找出原因。
解决方案
这可能不是最有效的方法,但它很灵活,因为您可以将 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
推荐阅读
- javascript - 有没有办法通过使用 .forEach 或 .map 而不是 for-loop 来解决这个问题?
- hyperledger - Hyperledger Composer 查询语言:如何使用资产 ID 从关系中取回资产?
- javascript - 优化修复html表格标题的功能,根据屏幕大小和内容实时调整不同的宽度
- c# - 如何获得从对象到空间映射的距离
- swift - 从 RSS 或网页解析 XML
- javascript - 如何在 VueJS 中使类的“虚拟”getter 具有响应性
- spring-boot - java.lang.NoSuchMethodError:org.springframework.boot.builder.SpringApplicationBuilder
- django - Django / Django rest framework 查看未捕获的异常
- json - 数据表未检测到 JSON 已被 Angular 读取
- javascript - 如何从 WordPress woocommerece 的数据库中获取电子邮件 ID 并将其存储到 java 脚本变量中?