您可以在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文件具有单个 #
分隔符。
诚然,它有时包含一个序列中的一些散列,但仅意味着
许多输入字段缺少(它们是空字符串)。
这就是为什么散列原则上位于之间的原因
实际上在您的文件中彼此相邻。
要注意的另一件事是 read_csv 的默认行为是
这样的空字符串将被转换为 NaN ,对于
缺少例如字符串。
要关闭此功能,请传递 na_filter = False 。
还请注意,由于只传递了默认值,因此不需要 quotechar 。
可能也不需要
engine 参数。
关于列名称的下一个备注是您的第一行
输入文件(列名)包含a.o。 烂番茄评分(一个
列),则您的列列表包含两个列:烂番茄
和 Rating (输入中不存在)。
因此删除 names 参数(您实际上尝试读取所有列)。
另一个细微的细节:如果您传递了 names 参数,则意味着:
- 您的输入不包含任何具有列名的行。
- 您可以自行指定它们。
从第一输入行开始读取- 数据行。
由于您的文件确实包含列名,因此实际上已读取它们
作为第一行数据。
如果您想将读数“限制”到源列的子集,
通过列列表传递 usecols 参数,但是正如我所见,您没有
需要它。
因此,总而言之,请尝试以下代码:
movies = pd.read_csv('movies.csv',sep='#',na_filter=False)
根据 11:58:03Z
的注释进行编辑
如果在第一个字段中仅“ 仅个哈希”(例如, Revolution#9
在第803行中),就有可能解决此问题。
想法是:
- 编写专门的解析器,对每行执行反向拆分
从输入文件中读取。
- 仅使用此解析器读取列名(从第一行输入)(因此
消耗第一行)。
- 使用以下命令创建一个调用 pd.DataFrame 的DataFrame:
- 仅将此解析器作为 data (它将读取“更多”行,即行
包含数据),
- 列列表以前读为列。
要做到这一点,请按如下所示定义解析器:
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个“预算”列都可以强制转换为 int ,而发布日期强制转换为 datetime 。
本文链接:https://www.f2er.com/2677658.html