2016-03-04 2 views
1

У меня есть dataframe Панды, которого каждая строка состоит из списка индексов (один столбец с именем «Индексы», который имеет разделенных запятой строку значения):преобразовать каждую строку в несколько колонок dataframe панды DataFrame

«Индексы '

'1,4,6,3,2,5,6,8'

'1,7,5,10,23,50'

Я хочу использовать применять для того, для создания новой матрицы (DataFrame?), каждая строка которой имеет 1 с значениями, указанными в соответствующей строке исходного фрейма, и 0 в другом месте. Предположим, что я знаю количество новых столбцов, так как у меня есть индексы min и max (например, 0 и 10). Я могу сделать это с помощью iterrows/itertuples и построить новую матрицу, но есть ли более эффективный способ сделать это? У меня есть матрица в 1 миллион строк, но даже при 100k это довольно долгое время.

[Пример]:

я буду примером и требуемый выход для простоты понимания:

предположить MAX_INDEX = 4 и MIN_INDEX = 0:

для ввода:

' 1,3,2,4'

'0,1'

OUTP ут будет 5-матрица-столбец с двумя рядами следующим образом:

[EDIT] вопрос остается - хотя я понял, это было очень медленным просто потому, что я создал новую матрицу, используя append, вместо выделения a-priori памяти и ввода только новых строк. поэтому одно решение:

m=np.empty(shape=[df.shape[0],numFeatures]) 
i=0 
for row in df.itertuples(): 
    idxs = row[4] # column of peattributes 
    idxs = map(lambda(x):int(x),idxs.split(',')) 
    r=np.zeros(numFeatures) 
    r[idxs] = 1 
    m[i,]=r 
    i+=1 

спасибо, Dan

+1

Можете ли вы показать нам ваш желаемый результат, на основе приведенного вами примера? – IanS

+0

Спасибо. Обновите исходный вопрос. – IanS

+0

Можете ли вы поместить эту информацию в исходный вопрос? Под ним есть кнопка редактирования. Это будет легче читать. – IanS

ответ

0

Edit: Это гораздо быстрее (в четыре раза), чтобы проверить, является ли строка, представляющая собой целое число в исходной строке:

rng_str = [str(i) for i in range(MIN_INDEX, MAX_INDEX+1)] 
s = df['Indexes'].apply(lambda row: [int(i in row) for i in rng_str]) 
pd.DataFrame(s.tolist()) 

Примечание: последний шаг преобразуется из серии списков в информационный кадр. Быстрее делать это в конце, а не внутри apply.


Оригинальный ответ ниже:

У меня есть решение, я бы любопытно знать, если он работает быстрее, чем ваша.Первый шаг преобразовать строку в список:

df['Indexes'] = df['Indexes'].apply(lambda s: [int(x) for x in s.split(',')]) 

можно затем использовать функцию apply, чтобы сгенерировать выходной построчно:

rng = range(MIN_INDEX, MAX_INDEX+1) 
df.apply(lambda row: [int(i in row['Indexes']) for i in rng], axis=1) 

Выход:

0 [0, 1, 1, 1, 1] 
1 [1, 1, 0, 0, 0] 
Смежные вопросы