通过使用切片列表从DataFrame获取行

时间:2018-09-29 00:06:08

标签: python pandas performance dataframe indexing

我有几百万行数据框,并且需要从中选择感兴趣的部分。我正在寻找一种高效的方法(读作:最快)。

我知道我可以做到:

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'

我主要关注的是性能。由于要处理的数据帧的大小,我需要最好的方法。

3 个答案:

答案 0 :(得分:4)

熊猫

您可以尝试一些技巧:

  1. 使用np.r_slice对象串联到单个NumPy数组中。使用NumPy数组建立索引通常是有效的,因为它们在Pandas框架内部使用。
  2. 通过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数组。首先通过上述slices定义np.r_,然后使用:

df['C'].values[slices] = 0

这会绕过Pandas界面以及通过常规索引方法进行的所有相关检查。

答案 1 :(得分:0)

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']

答案 2 :(得分:0)

您可以先尝试为行构建一个完整的索引器,然后进行分配:

row_indexer = pd.concat((df.index[sub_slice] for sub_slice in slices), axis=0)
df[row_indexer, column] = True