使用切片列表从 DataFrame 中获取行
Posted
技术标签:
【中文标题】使用切片列表从 DataFrame 中获取行【英文标题】:Get rows from a DataFrame by using a list of slices 【发布时间】:2019-03-04 22:59:39 【问题描述】:我有几百万行数据框,以及我需要从中选择的有趣部分的列表。我正在寻找一种高效(读作:最快)的方法来做到这一点。
我知道我能做到:
slices = [slice(0,10), slice(20,50), slice(1000,5000)]
for slice in slices:
df.loc[slice, 'somecolumn'] = True
...但这似乎是一种完成工作的低效方式。 真的很慢。
这似乎比上面的 for 循环更快,但我不确定这是否是最好的方法:
from itertools import chain
ranges = chain.from_iterable(slices)
df.loc[ranges, 'somecolumns'] = True
这也不起作用,尽管它似乎应该这样做:
df.loc[slices, 'somecolumns'] = True
TypeError: unhashable type: 'slice'
我最关心的是性能。由于我正在处理的数据帧的大小,我需要尽我所能。
【问题讨论】:
【参考方案1】:熊猫
你可以尝试几个技巧:
-
使用
np.r_
将slice
对象连接到单个NumPy 数组中。使用 NumPy 数组进行索引通常很有效,因为它们在 Pandas 框架内部使用。
通过pd.DataFrame.iloc
使用位置整数索引,而不是主要基于标签的loc
。前者限制性更强,并且与 NumPy 索引更接近。
这是一个演示:
# some example dataframe
df = pd.DataFrame(dict(zip('ABCD', np.arange(100).reshape((4, 25)))))
# concatenate multiple slices
slices = np.r_[slice(0, 3), slice(6, 10), slice(15, 20)]
# use integer indexing
df.iloc[slices, df.columns.get_loc('C')] = 0
numpy
如果您的系列保存在一个连续的内存块中,这通常是数字(或布尔)数组的情况,您可以尝试就地更新底层 NumPy 数组。首先通过np.r_
定义slices
,然后使用:
df['C'].values[slices] = 0
这会绕过 Pandas 接口和通过常规索引方法进行的任何相关检查。
【讨论】:
如果您已经创建了切片列表并希望将其与pandas
和np.r_
一起使用怎么办?直接使用np.r_[slices]
将不起作用(不会将切片转换为数组)。我可以做类似np.concatenate([np.r_[s] for s in slices])
的事情,然后将其用作pandas DataFrame 的索引。有没有更好的办法?【参考方案2】:
IIUC,您希望在轴 = 0(行索引)上进行切片。我使用 numpy 的 arange
方法而不是切片,并使用 df.ix
:
slices = np.append(np.arange(0,10), np.arange(20,50), np.arange(1000,5000)) ##add other row slices here
df.ix[slices, 'some_col']
【讨论】:
注意ix
自 v0.20.0 以来已被弃用。请改用loc
。【参考方案3】:
您可以先尝试为行构建一个完整的索引器,然后执行您的任务:
row_indexer = pd.concat((df.index[sub_slice] for sub_slice in slices), axis=0)
df[row_indexer, column] = True
【讨论】:
以上是关于使用切片列表从 DataFrame 中获取行的主要内容,如果未能解决你的问题,请参考以下文章
Pandas Dataframe 中的索引行不在索引列表中(Python)[重复]
Pandas:如何从给定(行,列)对列表的 DataFrame 中检索值?
pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用groups属性获取每个分组的样本对应的在原dataframe中的行索引位置列表