Does this work for you?
df.iloc[:N, :].to_csv()
Or
df.iloc[P:Q, :].to_csv()
I believe df.iloc generally produces references to the original dataframe rather than copying the data.
If this still doesn't work, you might also try setting the chunksize in the to_csv call. It may be that pandas is able to create the subset without using much more memory, but then it makes a complete copy of the rows written to each chunk. If the chunksize is the whole frame, you would end up copying the whole frame at that point and running out of memory.
If all else fails, you can loop through df.iterrows() or df.iloc[P:Q, :].iterrows() or df.iloc[P:Q, :].itertuples() and write each row using the csv module (possibly writer.writerows(df.iloc[P:Q, :].itertuples()).
chunksizeparameter of the.to_csv()method.to_csv(index=False))