Как сгенерировать фрейм данных, используя значения столбца в каком-либо другом кадре данных

Я работаю над набором данных, который находится в следующем кадре данных.

#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 миллионов строк, этот метод грубой силы занимает много времени. Есть ли способ лучше этого?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сначала отфильтруйте строки по членству с помощью 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

Я получаю следующую ошибку: ValueError: Unstacked DataFrame слишком велик, вызывая переполнение int32\n, так как я использую "|" вместо "&" при инициализации нового фрейма данных

Satheesh K 30.05.2019 13:06

@SatheeshK - Вам нужно | вместо or, а не & вместо and?

jezrael 30.05.2019 13:10

@SatheeshK - К сожалению, ошибка означает очень большие данные, какова длина списков selected_col1 и selected_col2?

jezrael 30.05.2019 13:12

Я использую | для или только. len(selected_col1)= 1894 ,len(selected_col2)= 8546

Satheesh K 30.05.2019 13:15

@SatheeshK - отредактированный ответ с разницей между ним.

jezrael 30.05.2019 13:16
old_df.shape = (20000263,3),new_df.shape = (19855757, 3)
Satheesh K 30.05.2019 13:18

@SatheeshK - Слишком большие данные для сводной операции, для работы требуется больше оперативной памяти, ваше более медленное решение или другая библиотека, такая как dask ...

jezrael 30.05.2019 13:20

@SatheeshK - Если хорошо понять, после фильтрации удаляются только несколько строк. Так что это причина странной ошибки, потому что большой DataFrame. Также одна вещь - вы можете попробовать обновиться до последней версии панд, может быть, это поможет.

jezrael 30.05.2019 13:23

Другие вопросы по теме