如何使用pandas过滤哪些CSV行加载到内存中?这似乎是read_csv
中应该找到的选项。我错过了什么吗?
示例:我们有一个带有时间戳列的CSV,我们只想加载时间戳大于给定常量的行。
答案 0 :(得分:119)
在将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
以适合您的可用内存。有关详细信息,请参阅here。
答案 1 :(得分:7)
我没有在read_csv
的上下文中找到直接的方法。但是,read_csv
会返回一个DataFrame,可以通过布尔向量df[bool_vec]
选择行来过滤:
filtered = df[(df['timestamp'] > targettime)]
这是选择df中的所有行(假设df是任何DataFrame,例如read_csv
调用的结果,至少包含日期时间列timestamp
),其中的值为{ {1}}列大于targettime的值。 Similar question
答案 2 :(得分:3)
如果过滤后的范围是连续的(通常是使用时间(时间戳)过滤器),那么最快的解决方案是对行范围进行硬编码。只需将skiprows=range(1, start_row)
与nrows=end_row
参数组合即可。然后,导入将花费数秒,而接受的解决方案将花费数分钟。考虑到导入时间的节省,使用初始start_row
进行的一些实验并不是很大的费用。请注意,我们使用range(1,..)
保留了标题行。
答案 3 :(得分:1)
您可以指定nrows
参数。
import pandas as pd
df = pd.read_csv('file.csv', nrows=100)
此代码在0.20.3版本中效果很好。
答案 4 :(得分:0)
如果您使用的是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
答案 5 :(得分:0)
可接受的答案的替代方法是将read_csv()应用于通过过滤输入文件而获得的StringIO。
with open(<file>) as f:
text = "\n".join([line for line in f if <condition>])
df = pd.read_csv(StringIO(text))
当过滤条件仅保留一小部分行时,此解决方案通常比接受的答案要快
答案 6 :(得分:0)
考虑您有以下数据框
+----+--------+
| 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 |
+----+--------+