如何在 Pandas read_csv 函数中过滤加载的行?
- 2025-02-27 09:07:00
- admin 原创
- 84
问题描述:
如何使用 pandas 过滤要加载到内存中的 CSV 行?这似乎是应该在 中找到的一个选项read_csv
。我遗漏了什么吗?
示例:我们有一个带有时间戳列的 CSV,并且我们只想加载时间戳大于给定常量的行。
解决方案 1:
在将 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
根据可用内存进行调整。请参阅此处了解更多详细信息。
解决方案 2:
我没有找到在上下文中执行此操作的直接方法read_csv
。但是,read_csv
返回一个 DataFrame,可以通过使用布尔向量选择行来过滤它df[bool_vec]
:
filtered = df[(df['timestamp'] > targettime)]
这是选择 df 中的所有行(假设 df 是任何 DataFrame,例如调用的结果read_csv
,至少包含一个 datetime 列timestamp
),其中列中的值timestamp
大于 targettime 的值。类似的问题。
解决方案 3:
接受答案的另一种方法是将 read_csv() 应用于通过过滤输入文件获得的 StringIO。
with open(<file>) as f:
text = "
".join([line for line in f if <condition>])
df = pd.read_csv(StringIO(text))
当过滤条件仅保留一小部分行时,此解决方案通常比接受的答案更快
解决方案 4:
如果过滤范围是连续的(时间(戳)过滤器通常都是连续的),那么最快的解决方案是对行范围进行硬编码。只需skiprows=range(1, start_row)
与nrows=end_row
参数结合即可。然后导入只需几秒钟,而接受的解决方案则需要几分钟。考虑到导入时间的节省,对初始版本进行一些实验的start_row
成本并不高。请注意,我们使用 保留了标题行range(1,..)
。
解决方案 5:
如果您使用的是 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
解决方案 6:
假设您有以下数据框
+----+--------+
| 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 |
+----+--------+
解决方案 7:
您可以指定nrows
参数。
`import pandas as pd
df = pd.read_csv('file.csv', nrows=100)`
该代码在0.20.3版本中运行良好。
扫码咨询,免费领取项目管理大礼包!