在典型的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)
并仅选择我想要的索引?
答案 0 :(得分:-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
祝你好运!