使用切片列表从 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 接口和通过常规索引方法进行的任何相关检查。

【讨论】:

如果您已经创建了切片列表并希望将其与pandasnp.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)[重复]

Python DataFrame循环和切片问题

按行切片 Pandas DataFrame

Pandas - 索引操作

Pandas:如何从给定(行,列)对列表的 DataFrame 中检索值?

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用groups属性获取每个分组的样本对应的在原dataframe中的行索引位置列表