繁体   English   中英

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

[英]How can I filter lines on load in Pandas read_csv function?

如何使用 Pandas 过滤要加载到内存中的 CSV 行? 这似乎是一个应该在read_csv找到的read_csv 我错过了什么吗?

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

在将 CSV 文件加载到 Pandas 对象之前,没有筛选行的选项。

您可以加载文件,然后使用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以满足您的可用内存。 请参阅此处了解更多详情。

我没有在read_csv上下文中找到一种直接的方法。 但是, read_csv返回一个数据帧,可以通过布尔向量df[bool_vec]选择行来过滤它:

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

这是选择 df 中的所有行(假设 df 是任何 DataFrame,例如read_csv调用的结果,它至少包含一个 datetime 列timestamp ),其中timestamp列中的值大于 targettime 的值。 类似的问题

如果过滤的范围是连续的(通常是使用时间戳(时间戳)过滤器),那么最快的解决方案是对行范围进行硬编码。 只需将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))

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

考虑您有以下数据框

+----+--------+
| 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 |
+----+--------+

如果您使用的是 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参数。

import pandas as pd df = pd.read_csv('file.csv', nrows=100)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM