首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pandas read_csv low_memory和dtype选项

Pandas read_csv low_memory和dtype选项
EN

Stack Overflow用户
提问于 2014-06-17 03:56:48
回答 11查看 467.5K关注 0票数 442

当调用

代码语言:javascript
运行
复制
df = pd.read_csv('somefile.csv')

我得到了:

/Users/josh/anaconda/envs/py27/lib/python2.7/site-packages/pandas/io/parsers.py:1130:

DtypeWarning:列(4,5,7,16)具有混合类型。在导入时指定dtype选项或设置low_memory=False。

为什么dtype选项与low_memory相关,为什么让它成为False可以帮助解决这个问题?

EN

Stack Overflow用户

发布于 2020-07-19 09:36:31

根据pandas documentation的说法,对于这个问题,只要指定low_memory=False就指定engine='c' (这是默认值)是一个合理的解决方案。

如果为low_memory=False,则将首先读取整个列,然后确定正确的类型。例如,列将根据需要作为对象(字符串)保留,以保留信息。

如果为low_memory=True (缺省值),那么pandas将以行块的形式读取数据,然后将它们追加到一起。然后,一些列可能看起来像是整数和字符串混合在一起的块,这取决于在块期间pandas是否遇到了任何无法转换为整数的内容(比方说)。这可能会在以后造成问题。该警告告诉您,这种情况在读入过程中至少发生了一次,因此您应该小心。设置low_memory=False将使用更多内存,但可以避免该问题。

就我个人而言,我认为low_memory=True是一个糟糕的默认设置,但我所在的领域使用的小数据集比大型数据集多得多,因此便利性比效率更重要。

下面的代码演示了一个示例,其中设置了low_memory=True,并以混合类型传入一个列。它通过@firelynx构建答案

代码语言:javascript
运行
复制
import pandas as pd
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

# make a big csv data file, following earlier approach by @firelynx
csvdata = """1,Alice
2,Bob
3,Caesar
"""

# we have to replicate the "integer column" user_id many many times to get
# pd.read_csv to actually chunk read. otherwise it just reads 
# the whole thing in one chunk, because it's faster, and we don't get any 
# "mixed dtype" issue. the 100000 below was chosen by experimentation.
csvdatafull = ""
for i in range(100000):
    csvdatafull = csvdatafull + csvdata
csvdatafull =  csvdatafull + "foobar,Cthlulu\n"
csvdatafull = "user_id,username\n" + csvdatafull

sio = StringIO(csvdatafull)
# the following line gives me the warning:
    # C:\Users\rdisa\anaconda3\lib\site-packages\IPython\core\interactiveshell.py:3072: DtypeWarning: Columns (0) have mixed types.Specify dtype option on import or set low_memory=False.
    # interactivity=interactivity, compiler=compiler, result=result)
# but it does not always give me the warning, so i guess the internal workings of read_csv depend on background factors
x = pd.read_csv(sio, low_memory=True) #, dtype={"user_id": int, "username": "string"})

x.dtypes
# this gives:
# Out[69]: 
# user_id     object
# username    object
# dtype: object

type(x['user_id'].iloc[0]) # int
type(x['user_id'].iloc[1]) # int
type(x['user_id'].iloc[2]) # int
type(x['user_id'].iloc[10000]) # int
type(x['user_id'].iloc[299999]) # str !!!! (even though it's a number! so this chunk must have been read in as strings)
type(x['user_id'].iloc[300000]) # str !!!!!

旁白:举一个例子,这是一个问题(我第一次遇到这个问题是一个严重的问题),假设您在一个文件上运行pd.read_csv(),然后想要根据标识符删除重复项。假设标识符有时是数字的,有时是字符串的。一行可能是"81287",另一行可能是"97324-32“。尽管如此,它们仍然是唯一标识符。

使用low_memory=True,pandas可能会读入标识符列,如下所示:

代码语言:javascript
运行
复制
81287
81287
81287
81287
81287
"81287"
"81287"
"81287"
"81287"
"97324-32"
"97324-32"
"97324-32"
"97324-32"
"97324-32"

就因为它是分块的,所以有时标识符81287是一个数字,有时是一个字符串。当我尝试删除基于此的副本时,

代码语言:javascript
运行
复制
81287 == "81287"
Out[98]: False
票数 4
EN
查看全部 11 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24251219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档