Как изменить содержимое фрейма с помощью словарей? [Дубликат]

Если все остальное не удается, перекомпилируйте.

Недавно я смог избавиться от нерешенной внешней ошибки в Visual Studio 2012, просто перекомпилировав нарушивший файл. Когда я перестроил, ошибка исчезла.

Это обычно происходит, когда две (или более) библиотеки имеют циклическую зависимость. Библиотека A пытается использовать символы в B.lib и библиотеке B пытается использовать символы из A.lib. Ничего не существует для начала. Когда вы пытаетесь скомпилировать A, шаг ссылки завершится неудачно, потому что он не может найти B.lib. A.lib будет сгенерирован, но не будет dll. Затем вы компилируете B, который будет успешным и сгенерирует B.lib. Повторная компиляция A теперь будет работать, потому что теперь найден B.lib.

142
задан TheChymera 1 December 2013 в 06:58
поделиться

6 ответов

Вы можете использовать .replace. Например:

>>> df = pd.DataFrame({'col2': {0: 'a', 1: 2, 2: np.nan}, 'col1': {0: 'w', 1: 1, 2: 2}})
>>> di = {1: "A", 2: "B"}
>>> df
  col1 col2
0    w    a
1    1    2
2    2  NaN
>>> df.replace({"col1": di})
  col1 col2
0    w    a
1    A    2
2    B  NaN

или непосредственно на Series, то есть df["col1"].replace(di, inplace=True).

164
ответ дан DSM 25 August 2018 в 18:42
поделиться

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

def multiple_replace(dict, text):
  # Create a regular expression  from the dictionary keys
  regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))

  # For each match, look-up corresponding value in dictionary
  return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) 

После того, как вы определили функцию, вы можете применить ее к вашему фреймворку данных.

di = {1: "A", 2: "B"}
df['col1'] = df.apply(lambda row: multiple_replace(di, row['col1']), axis=1)
0
ответ дан Amirhos Imani 25 August 2018 в 18:42
поделиться

map может быть намного быстрее, чем replace

Если ваш словарь содержит более двух ключей, использование map может быть намного быстрее, чем replace. Существуют две версии этого подхода, в зависимости от того, исчерпывает ли ваш словарь все возможные значения (а также хотите ли вы заменить несоответствия или оставить их как отсутствующие значения):

Исчерпывающее сопоставление

В этом случае форма очень проста:

df['col1'].map(di)       # note: if the dictionary does not exhaustively map all
                         # entries then non-matched entries are changed to NaNs

Хотя map чаще всего принимает функцию как свой аргумент, она может альтернативно принимать словарь или серию: Документация для Pandas.series.map

Неисчерпывающее сопоставление

Если у вас есть не исчерпывающее отображение и вы хотите сохранить существующие переменные для несоответствий, вы можете добавить fillna:

df['col1'].map(di).fillna(df['col1'])

, как в ответе @ jpp здесь: Заменить значения в серии pandas с помощью словаря эффективно

Тесты

Используя следующие данные с версией pandas 0.23.1:

di = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H" }
df = pd.DataFrame({ 'col1': np.random.choice( range(1,9), 100000 ) })

и тестируя с %timeit, похоже, что map примерно в 10 раз быстрее, чем replace.

Обратите внимание, что ваше ускорение с map будет отличаться в зависимости от ваших данных. Самое большое ускорение, похоже, связано с большими словарями и исчерпывающими заменами. См. Ответ @jpp (см. Выше) для более подробных тестов и обсуждения.

49
ответ дан JohnE 25 August 2018 в 18:42
поделиться

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

def remap(data,dict_labels):
    """
    This function take in a dictionnary of labels : dict_labels 
    and replace the values (previously labelencode) into the string.

    ex: dict_labels = {{'col1':{1:'A',2:'B'}}

    """
    for field,values in dict_labels.items():
        print("I am remapping %s"%field)
        data.replace({field:values},inplace=True)
    print("DONE")

    return data

Надеюсь, что это может быть полезно кому-то.

Cheers

g2]
2
ответ дан Nico Coallier 25 August 2018 в 18:42
поделиться

В вашем вопросе есть немного двусмысленности. Существует не менее трех двух интерпретаций:

  1. клавиши в di относятся к значениям индекса
  2. , клавиши в di относятся к df['col1'] значениям
  3. ключи в di относятся к местоположению индексов (а не к вопросу OP, но выбрасываются для удовольствия.)

Ниже приведено решение для каждого случая.


Случай 1: Если клавиши di предназначены для обозначения значений индекса, вы можете использовать метод update:

df['col1'].update(pd.Series(di))

Например,

import pandas as pd
import numpy as np

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
#   col1 col2
# 1    w    a
# 2   10   30
# 0   20  NaN

di = {0: "A", 2: "B"}

# The value at the 0-index is mapped to 'A', the value at the 2-index is mapped to 'B'
df['col1'].update(pd.Series(di))
print(df)

дает

  col1 col2
1    w    a
2    B   30
0    A  NaN

Я изменил значения из вашего исходного сообщения, чтобы было ясно, что делает update. Обратите внимание, что ключи из di связаны с значениями индекса. Порядок значений индекса, т. Е. Индекс местоположения - не имеет значения.


Случай 2: Если клавиши в di относятся к df['col1'], то @DanAllan и @DSM показывают, как достичь этого с помощью replace:

import pandas as pd
import numpy as np

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
print(df)
#   col1 col2
# 1    w    a
# 2   10   30
# 0   20  NaN

di = {10: "A", 20: "B"}

# The values 10 and 20 are replaced by 'A' and 'B'
df['col1'].replace(di, inplace=True)
print(df)

дает

  col1 col2
1    w    a
2    A   30
0    B  NaN

Обратите внимание, как в этом случае клавиши в di были изменены в соответствии с значениями в df['col1'].


Случай 3: Если клавиши в di относятся к местоположениям индекса, вы можете использовать

df['col1'].put(di.keys(), di.values())

, поскольку

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
di = {0: "A", 2: "B"}

# The values at the 0 and 2 index locations are replaced by 'A' and 'B'
df['col1'].put(di.keys(), di.values())
print(df)

дает

  col1 col2
1    A    a
2   10   30
0    B  NaN

Здесь первая и третья строки были изменены, поскольку клавиши в di являются 0 ] и 2, которые с индексом на основе индекса Python относятся к первому и третьему местоположениям.

49
ответ дан unutbu 25 August 2018 в 18:42
поделиться

DSM имеет принятый ответ, но в этом ответе немного ошибочно (я не уверен, что ответ когда-либо работал в готовом виде). Вот пример, который работает с текущей версией pandas (0.23.4 с 8/2018):

import pandas as pd

df = pd.DataFrame({'col1': [1, 2, 2, 3, 1],
            'col2': ['negative', 'positive', 'neutral', 'neutral', 'positive']})

conversion_dict = {'negative': -1, 'neutral': 0, 'positive': 1}
df['converted_column'] = df['col2'].replace(conversion_dict)

print(df.head())

Вы увидите, что это выглядит так:

   col1      col2  converted_column
0     1  negative                -1
1     2  positive                 1
2     2   neutral                 0
3     3   neutral                 0
4     1  positive                 1

Документы для pandas.DataFrame.replace здесь .

0
ответ дан wordsforthewise 25 August 2018 в 18:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: