Python 跳过读取csv中缺少值的行
我有一个非常大的csv,我需要读入。为了加快速度并节省内存使用量,我使用read_csv并将某些列的数据类型设置为np.uint32。问题是某些行缺少值,pandas使用浮点表示这些值Python 跳过读取csv中缺少值的行,python,pandas,Python,Pandas,我有一个非常大的csv,我需要读入。为了加快速度并节省内存使用量,我使用read_csv并将某些列的数据类型设置为np.uint32。问题是某些行缺少值,pandas使用浮点表示这些值 是否可以跳过缺少值的行?我知道在读取整个文件后可以这样做,但这意味着在此之前我无法设置数据类型,因此会使用太多的RAM 在读取数据期间,是否可以将缺少的值转换为我选择的其他值 如果你展示一些数据,ppl会有所帮助 pd.read_csv('FILE', keep_default_na=False) 首先,请尝试
如果你展示一些数据,ppl会有所帮助
pd.read_csv('FILE', keep_default_na=False)
首先,请尝试以下方法:
熊猫身上没有这样的特征。您可以在常规Python中实现它,如下所示:
import csv
import pandas as pd
def filter_records(records):
"""Given an iterable of dicts, converts values to int.
Discards any record which has an empty field."""
for record in records:
for k, v in record.iteritems():
if v == '':
break
record[k] = int(v)
else: # this executes whenever break did not
yield record
with open('t.csv') as infile:
records = csv.DictReader(infile)
df = pd.DataFrame.from_records(filter_records(records))
熊猫仍然在内部使用
csv
模块。如果上述性能出现问题,您可能可以使用Cython(熊猫也使用Cython)来加快速度。如果您可以在读取过程中用say0
填充NaN
,这将是一件非常精致的事情。也许熊猫git hub中的一个功能请求已准备就绪
使用转换器函数
但是,目前,您可以定义自己的函数来执行此操作,并将其传递给以下中的转换器
参数:
请注意,converters
接受一个dict
,因此您需要为要处理的每个列指定它。如果很多栏目受到影响,可能会有点令人厌烦。可以指定列名或数字作为键
还请注意,这可能会降低您的读取性能,具体取决于转换器
功能的处理方式。此外,如果在读取过程中只有一列需要处理NAN,则可以跳过适当的函数定义,改用lambda
函数:
df = pd.read_csv(file, converters={colWithNaN : lambda x: 0 if x == np.nan else x}, dtypes=...)
分块阅读
您还可以将文件分成小块进行读取,然后将其缝合在一起以获得最终输出。你可以用这种方式做很多事情。以下是一个示例:
result = pd.DataFrame()
df = pd.read_csv(file, chunksize=1000)
for chunk in df:
chunk.dropna(axis=0, inplace=True) # Dropping all rows with any NaN value
chunk[colToConvert] = chunk[colToConvert].astype(np.uint32)
result = result.append(chunk)
del df, chunk
请注意,此方法不会严格复制数据。有一段时间,chunk
中的数据在结果之后存在两次。append
语句,但只有chunksize
行重复,这是一个公平的交易。这个方法也可能比使用转换器函数快得多。你会考虑对数据进行预处理,比如“GRIP-V,InFiel.CSV>GooFr.CSV”?通过这种方式,您可能能够更快地消除“坏”行。但这取决于空值是在所有列中无效还是在某些列中无效。@JohnZwinck你能在基于Windows的机器上使用“grep”吗?@Merlin:是的,我能。@JohnZwinck不是你这个人,而是全局的你。(不再是windows用户)你认为OP可以吗?@JohnZwinck我可以预处理,但如果可能的话,我更愿意将处理全部放在一个文件中。也许Python可以调用grep并通过管道将输出读取_csv?我想这取决于表的输入中是否有所需的NaN。@Jasen,这是典型的伪代码。这并不意味着替代品的数量减少。可能正在读取的数据是空的,因此if
语句应该更改为if val为None:
。也许它还有其他代表性……谢谢。这回答了问题2。这个方法可以用来回答问题1吗。不知怎的?我不认为你可以使用熊猫。以一种会跳过缺少值的行的方式来阅读。如果一行中的所有值都丢失,则默认情况下,跳过空白行
kwag设置为True
,因此您对此无能为力。您是否想过将文件分块读取、处理并重新缝合在一起?我可以编辑我的答案,以包括该方法。如果您觉得您的问题已得到回答,请标记为已回答。谢谢。这似乎在RAM中创建了两个输入副本?第一个副本“记录”在类型转换之前包含整个文件。这正是我试图避免的。可能pandas.read\u csv
也容易出现数据重复。至少是这样,如果你读了《熊猫》的创造者韦斯·麦金尼的[本博客][1]。但请注意,该博客写于2012年10月,正如博客上的免责声明所说,已经有一段时间了,而且大部分信息都过时了。我不知道现代的、闪亮的read\u csv
在内存管理方面能做些什么。[1]:
df = pd.read_csv(file, converters={colWithNaN : lambda x: 0 if x == np.nan else x}, dtypes=...)
result = pd.DataFrame()
df = pd.read_csv(file, chunksize=1000)
for chunk in df:
chunk.dropna(axis=0, inplace=True) # Dropping all rows with any NaN value
chunk[colToConvert] = chunk[colToConvert].astype(np.uint32)
result = result.append(chunk)
del df, chunk