Вы можете прочитать csv в кусках. Поскольку pd.read_csv
возвращает итератор, когда задан параметр chunksize
, вы можете использовать itertools.takewhile
для чтения только столько фрагментов, сколько вам нужно, без чтения всего файла.
import itertools as IT
import pandas as pd
chunksize = 10 ** 5
chunks = pd.read_csv(filename, chunksize=chunksize, header=None)
chunks = IT.takewhile(lambda chunk: chunk['B'].iloc[-1] < 10, chunks)
df = pd.concat(chunks)
mask = df['B'] < 10
df = df.loc[mask]
Или, чтобы избежать необходимости использовать df.loc[mask]
для удаления нежелательных строк из последнего фрагмента, возможно, более чистым решением было бы определить пользовательский генератор:
import itertools as IT
import pandas as pd
def valid(chunks):
for chunk in chunks:
mask = chunk['B'] < 10
if mask.all():
yield chunk
else:
yield chunk.loc[mask]
break
chunksize = 10 ** 5
chunks = pd.read_csv(filename, chunksize=chunksize, header=None)
df = pd.concat(valid(chunks))
Я бы сказал легкий путь, описанный здесь:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#boolean-indexing
df[df['B'] > 10]
Вы можете использовать встроенный модуль csv
для вычисления соответствующего номера строки. Затем используйте pd.read_csv
с аргументом nrows
:
from io import StringIO
import pandas as pd
import csv, copy
mycsv = StringIO(""" A B C
34 3.20 'b'
24 9.21 'b'
34 3.32 'c'
24 24.3 'c'
35 1.12 'a'""")
mycsv2 = copy.copy(mycsv) # copying StringIO object [for demonstration purposes]
with mycsv as fin:
reader = csv.reader(fin, delimiter=' ', skipinitialspace=True)
header = next(reader)
counter = next(idx for idx, row in enumerate(reader) if float(row[1]) > 10)
df = pd.read_csv(mycsv2, delim_whitespace=True, nrows=counter+1)
print(df)
A B C
0 34 3.20 'b'
1 24 9.21 'b'
2 34 3.32 'c'
3 24 24.30 'c'
chunk.ix[-1, 'B']
? – unutbu 30 January 2015 в 18:15chunk.ix[-1, 'B']
вернет неправильное значение, если индексchunk
включил -1 в качестве значения. – unutbu 30 January 2015 в 18:19