【问题标题】:How to use Pandas to read CSV file with delimiter existing in the last field?如何使用 Pandas 读取最后一个字段中存在分隔符的 CSV 文件?
【发布时间】:2018-09-26 06:34:06
【问题描述】:

我有以下格式的原始数据:

JobID,Publish,Expire,TitleAndDetail
7428,17/12/2006 2:00:00 PM,28/01/2007 2:00:00 PM,Project Engineer - Mechanical      Looking,.....,....
7429,9/03/2006 2:00:00 PM,27/02/2007 2:00:00 PM,Supply Teacher      The job is,.....,.....

如您所见,分隔符是逗号,但最后一列是包含逗号的文本块。 我正在使用 pandas 的 read_csv 函数来读取这个 CSV 文件。但是在 pandas 数据框中,每行中第 4 个逗号之后的文本部分会丢失。

raw_data = pd.read_csv(r"/ABC/JobDetails.csv",
                       names=['JobID', 'Publish', 'Expire', 'TitleAndDetail'],
                       header=None
                       )

如果使用string.split() 函数,我可以指定一个maxsplit 参数,即使有很多逗号,我也可以将所有内容保留在最后一列。 Pandas 中是否有类似的功能?

【问题讨论】:

  • 您应该尝试获取一个以制表符作为分隔符 (.tsv) 的数据集,它对您的用例更稳定。另一种选择是用双引号“”包裹你的元素。这将使它假定它是一个组合条目,转义了元素内的所有逗号。
  • 您的文件格式不正确;所以试图绕过这个基本上是忽略问题(原始文件应该有引用的字段)。

标签: python pandas csv


【解决方案1】:

手动读取文件,然后创建数据框:

rows = []

with open('somefile.csv') as f:
  keys = next(f).split(',')
  for line in f:
     rows.append(dict(zip(keys, line.split(',', 3))))

df = pd.DataFrame(rows)

.split 采用可选参数来限制它在分隔符上拆分的次数。传递 3 意味着它会忽略最后一个字段中的逗号:

>>> s.split(',', 3)
['7428',
 '17/12/2006 2:00:00 PM',
 '28/01/2007 2:00:00 PM',
 'Project Engineer - Mechanical      Looking,.....,....']

接下来,我们使用标题行中的键和数据行中的值创建一个字典:

>>> f = 'JobID,Publish,Expire,TitleAndDetail'.split(',')
>>> dict(zip(f, s.split(',', 3)))
{'JobID': '7428',
 'Publish': '17/12/2006 2:00:00 PM',
 'Expire': '28/01/2007 2:00:00 PM',
 'TitleAndDetail': 'Project Engineer - Mechanical      Looking,.....,....'}

最后,我们列出这些字典(在rows 中),并将其作为参数传递以创建我们的数据框对象。

【讨论】:

    【解决方案2】:

    你可以这样做:

    with open("file.csv", "r") as fp:
        reader = csv.reader(fp, delimiter=",")
        rows = [x[:3] + [','.join(x[3:])] for x in reader]
        df = pd.DataFrame(rows)
        df.columns = df.iloc[0]
        df = df.reindex(df.index.drop(0))
        print df
    

    【讨论】:

      【解决方案3】:

      所以这里有一些你可以尝试的技巧:

      raw_data = pd.read_csv(r"/ABC/JobDetails.csv",
                             squeeze=True,
                             sep="\a"
                             )
      

      这应该给你一个系列忽略“,s”

      那么你可以这样做:

      df = raw_data.str.split(",", n=4, expand=True)
      df.columns = ['JobID', 'Publish', 'Expire', 'TitleAndDetail']
      

      这应该分成 4 列并重命名

      【讨论】:

      • 感谢您的回答。但是raw_data.str 在我的电脑上显示错误:AttributeError: 'DataFrame' object has no attribute 'str'。
      • 是的,很抱歉,请参阅我的编辑,为此,您需要选择数据中不存在的分隔符,以便不会拆分任何内容
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 2022-10-14
      相关资源
      最近更新 更多