如何将带有 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 Tomatoes
和 Rating,它们不存在于您的输入中。
所以删除 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.
我有这个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 Tomatoes 和 Rating,它们不存在于您的输入中。
所以删除 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.