pandas读取CSV文件并仅保留特定行(Python)

13

我知道skiprows参数可以允许你传入要跳过的行的索引列表。但是,我有一些行的索引想要保留。

假设我的CSV文件有数百万行,长这个样子:

  A B
0 1 2
1 3 4
2 5 6
3 7 8
4 9 0

我想要加载的索引列表只有2和3,所以

index_list = [2,3]

skiprows函数的输入应该是[0,1,4],但是我只有[2,3]可用。

我正在尝试类似这样的操作:

pd.read_csv(path, skiprows = ~index_list)

但是没有运气...你有什么建议吗?

感谢并且我非常感激所有的帮助。


你能提供精确的代码而不是模板吗? - Sreejith Menon
@ Sreejith 希望现在更易读了。 - dleal
3个回答

18

你可以在skiprows参数中传入一个lambda函数。例如:

rows_to_keep = [2,3]
pd.read_csv(path, skiprows = lambda x: x not in rows_to_keep)

您可以在此处的文档中阅读更多相关信息。


4
我进行了一些测试并发现,对于参数skiprows使用列表传递要比使用lambda函数传递快得多。传递一个列表似乎是O(1),而传递lambda函数则是O(N)。因此,对于非常大的CSV文件,我强烈建议首先从已知要保留的行的列表中生成要跳过的行的列表,就像gabra的答案那样。*(截至pandas v1.4.1的结果)* - mimocha

13

我认为首先需要找到行数,就像这个

num_lines = sum(1 for line in open('myfile.txt'))

那么您需要删除index_list的索引:

to_exclude = [i for i in num_lines if i not in index_list]

然后加载您的数据:

pd.read_csv(path, skiprows = to_exclude)

谢谢,gabra。我想我必须做类似的事情。看起来很奇怪有skiprows但没有读取特定行的函数。 - dleal
@dleal 我同意你的观点。这个链接也与你的问题相关。 - gabra
4
你需要把 [i for i in range(num_lines) if i not in index_list] 填进去,对吧?num_lines 不可迭代,是一个整数。 - Nabla

1
另一个简单的解决方法是在调用read_csv之后立即调用.loc。类似这样:
index_to_keep = [2, 4]
pd.read_csv(path).loc[index_to_keep]

注意: 这是一种较慢的方法,因为整个文件将首先被加载到内存中,然后才会选择所需的行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接