【问题标题】:Selecting rows from sparse dataframe by index position按索引位置从稀疏数据框中选择行
【发布时间】:2016-11-09 01:34:38
【问题描述】:

在典型的 python 数据框中,很容易根据索引选择所需的行:

df.ix[list_of_inds] or df.loc[list_of_inds]

但是,使用这种方法获取大型稀疏数据帧(具体为 73,000 行,8,000 列)的大部分子集似乎非常密集 - 我的内存猛增,我的计算机崩溃了。

我确实注意到使用这样的范围进行索引..

df.ix[1:N]

工作正常,同时使用这样的索引列表......

df.ix[np.arange(1,N)]

是导致内存过载的原因。

是否有另一种方法可以从计算上更容易的稀疏数据框中选择行?或者,我可以将此数据帧转换为实际的稀疏矩阵吗...

sparse_df = scipy.sparse.csc(df)

然后只选择我想要的索引?

【问题讨论】:

  • 你试过to_sparse的方法吗? pandas.pydata.org/pandas-docs/stable/sparse.html
  • 尝试一下 - 似乎需要一段时间。从 to_sparse 方法得到的数据帧可以很容易地被子集化吗?编辑:在我的 73000x8000 数据帧上使用 to_sparse 导致我的计算机崩溃
  • 你试过了吗:list_of_inds = pd.Index(list_of_inds); df.ix[list_of_inds]

标签: python numpy pandas scipy sparse-matrix


【解决方案1】:

您面临的问题可能与视图与复制语义有关。

df.ix[1:N]              # uses slicing => operates on a view 
df.ix[np.arange(1,N)]   # uses fancy indexing => "probably" creates a copy first

我在形状为 73000x8000 的机器上创建了一个 DataFrame,我的内存飙升至 4.4 GB,因此我不会对崩溃感到惊讶。也就是说,如果您确实需要使用索引列表创建一个新数组,那么您就不走运了。但是,要修改原始 DataFrame,您应该能够一次修改 DataFrame 一行,或者一次修改几个切片行,但会牺牲速度,例如:

for i in arbitrary_list_of_indices:
    df.ix[i] = new_values 

顺便说一句,您可以尝试直接处理 numpy 数组,我觉得它更清楚地描述了哪些操作会导致副本与视图。您始终可以从数组创建一个 DataFrame,几乎没有任何内存开销,因为它只是创建对原始数组的引用。

即使没有切片,numpy 中的索引也似乎更快。这是一个简单的测试用例:

In [66]: df
Out[66]: 
    0   1   2   3
0   3  14   5   1
1   9  19  14   4
2   5   4   5   5
3  13  14   4   7
4   8  12   3  16
5  15   3  17  12
6  11   0  12   0

In [68]: df.ix[[1,3,5]]       # fancy index version
Out[68]: 
    0   1   2   3
1   9  19  14   4
3  13  14   4   7
5  15   3  17  12

In [69]: df.ix[1:5:2]   # sliced version of the same
Out[69]: 
    0   1   2   3
1   9  19  14   4
3  13  14   4   7
5  15   3  17  12

In [71]: %timeit df.ix[[1,3,5]] = -1   # use fancy index version
1000 loops, best of 3: 251 µs per loop

In [72]: %timeit df.ix[1:5:2] = -2     # faster sliced version
10000 loops, best of 3: 157 µs per loop

In [73]: arr = df.values
In [74]: arr
Out[74]: 
array([[ 3, 14,  5,  1],
       [-2, -2, -2, -2],
       [ 5,  4,  5,  5],
       [-2, -2, -2, -2],
       [ 8, 12,  3, 16],
       [-2, -2, -2, -2],
       [11,  0, 12,  0]])

In [75]: %timeit arr[[1,3,5]] = -1   # much faster than DataFrame
The slowest run took 23.49 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 4.56 µs per loop

In [77]: %timeit arr[1:5:2] = -3  # really fast but restricted to slicing
The slowest run took 19.46 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 821 ns per loop

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-10
    • 2019-03-10
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 2018-09-26
    • 2014-11-30
    相关资源
    最近更新 更多