如何在 Pandasread_csv 函数中过滤加载行?

我如何过滤一个 CSV 的哪些行要加载到内存使用熊猫?这似乎是人们应该在 read_csv中找到的一个选项。我错过了什么吗?

例如: 我们有一个带有时间戳列的 CSV,我们希望只加载时间戳大于给定常量的行。

103509 次浏览

read_csv的背景下,我没有找到一种直截了当的方法来做到这一点。但是,read_csv返回一个 DataFrame,可以通过布尔向量 df[bool_vec]选择行来过滤它:

filtered = df[(df['timestamp'] > targettime)]

这是选择 df 中的所有行(假设 df 是任何 DataFrame,比如 read_csv调用的结果,至少包含一个 datetime 列 timestamp) ,对于这些行,timestamp列中的值大于 targettime 的值。同样的问题.

在 CSV 文件加载到熊猫对象之前,没有过滤行的选项。

你可以加载文件,然后使用 df[df['field'] > constant]进行过滤,或者如果你有一个非常大的文件,你担心内存耗尽,然后使用迭代器,在你连接文件块时应用过滤器,例如:

import pandas as pd
iter_csv = pd.read_csv('file.csv', iterator=True, chunksize=1000)
df = pd.concat([chunk[chunk['field'] > constant] for chunk in iter_csv])

您可以改变 chunksize以适应您的可用内存。请参阅 here了解更多细节。

如果你在 Linux 上,你可以使用 grep。

# to import either on Python2 or Python3
import pandas as pd
from time import time # not needed just for timing
try:
from StringIO import StringIO
except ImportError:
from io import StringIO




def zgrep_data(f, string):
'''grep multiple items f is filepath, string is what you are filtering for'''


grep = 'grep' # change to zgrep for gzipped files
print('{} for {} from {}'.format(grep,string,f))
start_time = time()
if string == '':
out = subprocess.check_output([grep, string, f])
grep_data = StringIO(out)
data = pd.read_csv(grep_data, sep=',', header=0)


else:
# read only the first row to get the columns. May need to change depending on
# how the data is stored
columns = pd.read_csv(f, sep=',', nrows=1, header=None).values.tolist()[0]


out = subprocess.check_output([grep, string, f])
grep_data = StringIO(out)


data = pd.read_csv(grep_data, sep=',', names=columns, header=None)


print('{} finished for {} - {} seconds'.format(grep,f,time()-start_time))
return data

可以指定 nrows参数。

进口大熊猫 Df = pd.read _ csv (‘ file.csv’,nrows = 100)

这段代码在0.20.3版本中运行良好。

如果筛选的范围是连续的(通常与时间(戳记)筛选器一样) ,那么最快的解决方案是对行的范围进行硬编码。只需将 skiprows=range(1, start_row)nrows=end_row参数结合起来。然后导入需要几秒钟,而接受的解决方案需要几分钟。考虑到节省了导入时间,使用初始 start_row进行一些试验并不是一个巨大的成本。注意,我们使用 range(1,..)保留了标题行。

可接受答案的另一种方法是将 read _ csv ()应用到 StringIO,这是通过过滤输入文件获得的。

with open(<file>) as f:
text = "\n".join([line for line in f if <condition>])


df = pd.read_csv(StringIO(text))

当过滤条件只保留一小部分行时,这个解决方案通常比已接受的答案更快

Consider you have the below dataframe

+----+--------+
| Id | Name   |
+----+--------+
|  1 | Sarath |
|  2 | Peter  |
|  3 | James  |
+----+--------+

如果需要过滤 Id = 1的记录,可以使用下面的代码。

df = pd.read_csv('Filename.csv', sep = '|')
df = df [(df ["Id"] == 1)]

这将产生以下输出。

+----+--------+
| Id | Name   |
+----+--------+
|  1 | Sarath |
+----+--------+