如何将带有 multi-character 分隔符的 csv-file 导入 Python 中的数据框?

How can I import csv-file with multi-character delimiters into dataframe in Python?

我有这个movies.csvcsv-file which I am to import into dataframe named 'movies'. But I have some troubles with erasing these #, ##, ###, #### delimiters. enter image description here 我试过这段代码:

    import pandas as pd
my_cols=["Title", "US Gross", "Worldwide Gross", "Production Budget", "Release Date", "Distributor", "Source", "Major Genre", "Creative Type","Director","Rotten Tomatoes","Rating","IMDB Rating","IMDB Votes"]
movies=pd.read_csv('movies.csv', 
                   sep="\#\#\#\#",
                   quotechar='"',
                   names=my_cols,
                   engine="python")
movies

但它仍然留下这个符号“#”并且只生成 1 列。请帮忙解决这个问题。

这是 CSV 中的几行: 标题#US Gross#Worldwide Gross#Production Budget#Release Date#Distributor#Source#Major Genre#Creative Type#Director#Rotten Tomatoes Rating#IMDB 土地女孩#146083#"146083"#"8000000"#12.6.1998#Gramercy####""##6,1#1071

您可以在 sep 参数中提供一个正则表达式来指示您只希望 # 字符作为分隔符,如下所示:

my_cols=["Title", "US Gross", "Worldwide Gross", "Production Budget", "Release Date", "Distributor", "Source", "Major Genre", "Creative Type","Director","Rotten Tomatoes","Rating","IMDB Rating","IMDB Votes"]
movies=pd.read_csv('Downloads/movies.csv', 
                   sep="#{1}",
                   quotechar='"',
                   names=my_cols,
                   engine="python",
                   skiprows=1)

我注意到的第一件事是你的 CSV 文件有一个 single # 作为 分隔符。

不可否认,它有时包含一个序列中的几个哈希值,但这意味着只有 许多输入字段 缺失 (它们是空字符串)。 这就是为什么散列按原则 连续字段之间定位的原因 实际上在您的文件中彼此相邻。

另一件需要注意的事情是 read_csv 的默认行为是 这样的空字符串被转换为NaN,这不是最好的选择 失踪例如字符串。

要关闭此功能,请传递 na_filter=False

另请注意,不需要 quotechar,因为您只传递了它的默认值。

engine 参数可能也不需要。

关于列名的下一个评论是你的第一行 输入文件(列名)包含 a.o。 烂番茄评分 (一个 列),而您的列列表包含 两个 列:Rotten TomatoesRating,它们不存在于您的输入中。

所以删除 names 参数(你实际上试图读取 all 列)。

另一个微妙的细节:如果你传递了 names 参数,这意味着:

  • 您的输入不包含任何带有列名称的行。
  • 你自己指定。
  • 数据行从 第一个 输入行开始读取。

因为你的文件确实包含列名,它们实际上被读取了 作为第一行数据

如果您想"limit"读取源列的子集, 将 usecols 参数与列列表一起传递,但正如我所见,您没有 需要它

所以,总结一下,试试下面的代码:

movies = pd.read_csv('movies.csv', sep='#', na_filter=False)

根据 11:58:03Z

的评论进行编辑

如果 "additional" 散列在第一个字段中 (例如 Revolution#9 在第803行),有可能解决这个问题。

想法是:

  • 编写专门的解析器,对每一行执行反向拆分 从输入文件中读取。
  • 仅使用此解析器读取列名(从第一行输入)(因此 消耗第一行)。
  • 创建一个调用 pd.DataFrame 的 DataFrame:
    • 只是这个解析器作为 data(它将读取 "further" 行,即行 包含数据),
    • 列列表之前读取为

为此,按如下方式定义解析器:

def parse_file(fn, sep, maxsplit):
    with open(fn) as f:
        for line in f:
            fields = line.strip().rsplit(sep, maxsplit)
            yield [ tt.strip('"') for tt in fields ]

然后,而不是 read_csv,运行:

myParser = parse_file('input.csv', '#', 12)
cols = next(myParser)
df = pd.DataFrame(myParser, columns=cols)

请注意,删除某些字段周围的双引号的任务 已在解析器中实现(参见 tt.strip('"'))。

然而,以这种方式读取的 DataFrame 具有 string 类型的所有列。 因此,您应该将特定的列转换为适当的类型。 例如。所有 3 "budget" 列都可以转换为 int 并且 Release Date 可以转换为 datetime.