2016-07-06 2 views
2

В типичном питона dataframe, это легко выбрать нужные строки на основе индекса:Выбор строки из разреженной dataframe по позиции индекса

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

Однако, используя этот метод, чтобы принять существенное подмножество большой, редкие dataframe (73 000 строк, 8000 столбцов), кажется, чрезвычайно интенсивным - моя память вспыхивает, и мой компьютер падает.

Я заметил, что индексация с использованием диапазона, как это ..

df.ix[1:N] 

работает отлично, при использовании списка индексов, как это ...

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

, что делает перегрузки памяти ,

Есть ли другой способ выбора строк из разреженного блока данных, который проще вычислить? Или я могу преобразовать это dataframe к фактической разреженной матрице ...

sparse_df = scipy.sparse.csc(df) 

и выбрать только те показатели, которые я хочу от этого?

+0

Вы пробовали метод 'to_sparse'? http://pandas.pydata.org/pandas-docs/stable/sparse.html – breucopter

+0

Попытка - похоже, это требует времени. Может ли получаемый результирующий фрейм от метода to_sparse быть легко подмножеством? Редактировать: использование to_sparse на моем 73000x8000 фреймворке разбило мой компьютер –

+0

Вы пытались: 'list_of_inds = pd.Index (list_of_inds); df.ix [list_of_inds] '? – MaxU

ответ

0

Проблема, с которой вы сталкиваетесь, может быть связана с семантикой просмотра и копирования.

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

Я создал DataFrame на моей машине формы 73000x8000 и моя память подскочила до 4,4 Гб, так что я не удивлюсь с ударами. Тем не менее, если вам нужно создать новый массив с индексным списком, то вам не повезло. Однако, чтобы изменить исходный DataFrame, вы должны быть в состоянии изменить DataFrame одну строку за один раз, или несколько нарезанных строк в то время, за счет скорости, например:

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

Btw, вы могли бы попробовать работать которые я чувствовал, имеет более четкие описания, какие операции приводят к копиям против представлений. Вы всегда можете создать 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 

Удачи!

 Смежные вопросы

  • Нет связанных вопросов^_^