【问题标题】:Read a df, split each cell and append to a list读取 df,拆分每个单元格并附加到列表
【发布时间】:2020-04-03 13:13:51
【问题描述】:

我正在处理一个包含多列的 csv 文件。 该文件看起来像这样......

A,B,C
1,'x;y;z','e;f;g'
2,'w;x;y','r;s;t'
3,'','p;q;r'

文件中的每个单元格都有一个用“;”分隔的字符串。

我想通过读取每个单元格并根据分隔符拆分每个单元格来创建一个列表。

我已经能够做到这一点,但存在性能问题。

csv 文件很大,所以我正在寻找一个优化的版本。

列名是预先知道的。我的代码如下所示

我目前的解决方案是 制作一个列表,读取每列中的所有行 展平列表 如果项目是字符串,则拆分列表中的项目,附加到新列表 从列表中删除重复项

import pandas as pd

from io import StringIO
from collections import Iterable
import operator


csv_path ='my_dir'
# load the data with pd.read_csv
dataDF = pd.read_csv(csv_path)
dataDF.fillna(" ")
result=[]
cols=['A','B','C']

for i in cols:
    result.append(dataDF[i].tolist())

result=reduce(operator.concat, result)
print(result)
my_list=[]
for token in result:
    if isinstance(token, str):
        my_list.append(token.split(";"))

my_list=reduce(operator.concat, my_list)
my_list=list(set(my_list))

【问题讨论】:

  • 对于初学者,您可以从一开始就将my_list 定义为set()my_list.append(token.split(";")) 将是 my_set.add(token.split(";"))。并添加你会做的结尾my_list = list(my_set)
  • 另外,fillna 没有赋值,所以它不起作用(需要 inplace=True)。我不确定我是否完全理解这里的问题,但似乎 df[col].str.split(';') 和 .str 机器的其余部分在这里工作得很好。
  • @OlegO 我已经添加了示例文件结构。希望它能解释我想要做什么。我的代码有效。但它很慢。我正在寻找优化的解决方案。谢谢

标签: python-3.x pandas loops csv


【解决方案1】:

如果你有很多重复的值,这可能会更快。

from itertools import chain

# load the data with pd.read_csv
dataDF = pd.DataFrame({'A': [1, 2, 3], 'B': ['x;y;z', 'w;x;y', ''], 'C': ['e;f;g', 'r;s;t', 'p;q;r']})
dataDF.fillna(" ", inplace=True)
results_set = set()
for i in dataDF.columns:
    try:
        results_set.update(chain(*dataDF[i].str.split(';').values))
    except AttributeError:
        pass
print(results_set)

【讨论】:

  • 是的。这个成功了。非常感谢您的时间和帮助。
【解决方案2】:

试试这个:

from itertools import chain

# load the data with pd.read_csv
dataDF = pd.DataFrame({'A': [1, 2, 3], 'B': ['x;y;z', 'w;x;y', ''], 'C': ['e;f;g', 'r;s;t', 'p;q;r']})
dataDF.fillna(" ", inplace=True)
list_of_lists = []
for i in dataDF.columns:
    try:
        list_of_lists.extend(dataDF[i].str.split(';').values)
    except AttributeError:
        pass
print(set(chain(*list_of_lists)))

【讨论】:

  • 谢谢。在我的 csv 文件中有大约 100k 行。有 15 列,每个单元格由一个字符串组成,其中包含 30 个项目,以“;”分隔。我已经运行了上面的代码,现在已经运行了 15 分钟以上。我使用的是 8 GB RAM 的 Windows 10 笔记本电脑。
猜你喜欢
  • 2019-08-05
  • 1970-01-01
  • 2019-03-07
  • 2015-03-01
  • 1970-01-01
  • 2018-08-30
  • 2021-04-24
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多