我有大型csvs,我只对行的子集感兴趣.特别是,我想读入在满足特定条件之前出现的所有行.
例如,如果read_csv将产生数据帧:
A B C
1 34 3.20 'b'
2 24 9.21 'b'
3 34 3.32 'c'
4 24 24.3 'c'
5 35 1.12 'a'
...
1e9 42 2.15 'd'
Run Code Online (Sandbox Code Playgroud)
有没有办法读取csv中的所有行,直到col B超过10.在上面的例子中,我想读入:
A B C
1 34 3.20 'b'
2 24 9.21 'b'
3 34 3.32 'c'
4 24 24.3 'c'
Run Code Online (Sandbox Code Playgroud)
我知道如何在读取数据帧后将这些行抛出,但此时我已经花了所有计算读取它们.在读取csv之前,我无法访问最后一行的索引(请不要跳过鞋子)
unu*_*tbu 14
你可以用块读取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]
Run Code Online (Sandbox Code Playgroud)
或者,为了避免必须使用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))
Run Code Online (Sandbox Code Playgroud)
警告:在处理之前
pd.read_csv("filename.csv")将整个内容加载csv到内存中DataFrame(感谢@BlackJack 指出了这一点)。如果csv很大 @unutbu 答案更合适(或者可能是另一个类似的库polars,它可以分块读取文件并通过其查询规划器应用多个操作)
基于@joanwa 的回答:
df = (pd.read_csv("filename.csv")
[lambda x: x['B'] > 10])
Run Code Online (Sandbox Code Playgroud)
来自 Wes McKinney 的“Python for Data Analysis”章节中的“Advanced pandas”:
在将 load_data 的结果分配给临时变量 df 之前,我们无法引用它。为了帮助解决这个问题,分配和许多其他 pandas 函数接受类似函数的参数,也称为可调用函数。
要显示正在运行的可调用对象,请考虑...
df = load_data()
df2 = df[df['col2'] < 0]
Run Code Online (Sandbox Code Playgroud)
可以重写为:
df = (load_data()
[lambda x: x['col2'] < 0])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13684 次 |
| 最近记录: |