Я работаю над набором данных, который находится в следующем кадре данных.
#print(old_df)
col1 col2 col3
0 1 10 1.5
1 1 11 2.5
2 1 12 5,6
3 2 10 7.8
4 2 24 2.1
5 3 10 3.2
6 4 10 22.1
7 4 11 1.3
8 4 89 0.5
9 4 91 3.3
Я пытаюсь создать другой фрейм данных, который содержит выбранные значения col1 в качестве индекса, выбранные значения col2 в качестве столбцов и присвоить соответствующее значение col3.
Например:
selected_col1 = [1,2]
selected_col2 = [10,11,24]
Новый фрейм данных должен выглядеть так:
#print(selected_df)
10 11 24
1 1.5 2.5 Nan
2 7.8 Nan 2.1
Я пробовал следующий метод
selected_col1 = [1,2]
selected_col2 = [10,11,24]
selected_df =pd.DataFrame(index=selected_col1,columns=selected_col2)
for col1_value in selected_col1:
for col2_value in selected_col2:
qry = 'col1 == {} & col2 == {}'.format(col1_value,col2_value)
col3_value = old_df.query(qry).col3.values
if (len(col3_value) > 0):
selected_df.at[col1_value,col2_value] = col3_value[0]
Но поскольку в моем фрейме данных около 20 миллионов строк, этот метод грубой силы занимает много времени. Есть ли способ лучше этого?
Сначала отфильтруйте строки по членству с помощью Series.isin
в обоих столбцах, связанных &
для побитового AND
, а затем используйте DataFrame.pivot
:
df = df[df['col1'].isin(selected_col1) & df['col2'].isin(selected_col2)]
df = df.pivot('col1','col2','col3')
print (df)
col2 10 11 24
col1
1 1.5 2.5 NaN
2 7.8 NaN 2.1
Если возможно, некоторые дублированные пары в col1
с col2
после фильтрации используют DataFrame.pivot_table
:
df = df.pivot_table(index='col1',columns='col2',values='col3', aggfunc='mean')
Обновлено:
Если использовать |
для побитового OR
, вы получите другой результат:
df = df[df['col1'].isin(selected_col1) | df['col2'].isin(selected_col2)]
df = df.pivot('col1','col2','col3')
print (df)
col2 10 11 12 24
col1
1 1.5 2.5 5,6 NaN
2 7.8 NaN NaN 2.1
3 3.2 NaN NaN NaN
4 22.1 1.3 NaN NaN
@SatheeshK - Вам нужно |
вместо or
, а не &
вместо and
?
@SatheeshK - К сожалению, ошибка означает очень большие данные, какова длина списков selected_col1
и selected_col2
?
Я использую |
для или только. len(selected_col1)= 1894
,len(selected_col2)= 8546
@SatheeshK - отредактированный ответ с разницей между ним.
old_df.shape = (20000263,3)
,new_df.shape = (19855757, 3)
@SatheeshK - Слишком большие данные для сводной операции, для работы требуется больше оперативной памяти, ваше более медленное решение или другая библиотека, такая как dask ...
@SatheeshK - Если хорошо понять, после фильтрации удаляются только несколько строк. Так что это причина странной ошибки, потому что большой DataFrame. Также одна вещь - вы можете попробовать обновиться до последней версии панд, может быть, это поможет.
Я получаю следующую ошибку: ValueError: Unstacked DataFrame слишком велик, вызывая переполнение int32\n, так как я использую "|" вместо "&" при инициализации нового фрейма данных