Замена значений в фрейме данных из другого фрейма данных - PullRequest
0 голосов
/ 08 декабря 2018

Итак, я работаю с набором данных с двумя фреймами данных.Фреймы данных выглядят так:

df1:

Item_ID  Item_Name
0        A
1        B
2        C

df2:

Item_slot_1   Item_slot_2  Item_Slot_3
2             2            1
1             2            0
0             1            1

Значения в df2 представляют Item_ID из df1.Как я могу заменить значения в df2 из item_id на фактическое имя элемента, чтобы df2 мог выглядеть так:

Item_slot_1   Item_slot_2  Item_Slot_3
C             C            B
B             C            A
A             B            B

Набор данных в реальности намного больше и имеет гораздо больше идентификаторов и имен, чем просто, б и с

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

Вы можете улучшить скорость отображения словаря с помощью numpy.Если ваши элементы пронумерованы 0-N, это тривиально, если нет, то это становится немного сложнее, но все же легко выполнимо.


Если элементы в df1 пронумерованы 0-N, используйте базовую индексацию:

a = df1['Item_Name'].values
b = df2.values

pd.DataFrame(a[b], columns=df2.columns)

  Item_slot_1 Item_slot_2 Item_Slot_3
0           C           C           B
1           B           C           A
2           A           B           B

Если они не пронумерованы 0-N, вот более общий подход:

x = df1['Item_ID'].values
y = df1['Item_Name'].values
z = df2.values

m = np.arange(x.max() + 1, dtype=object)
m[x] = y

pd.DataFrame(m[z], columns=df2.columns)

  Item_slot_1 Item_slot_2 Item_Slot_3
0           C           C           B
1           B           C           A
2           A           B           B

Заменить только подмножество столбцов из df2 также просто, давайте продемонстрируем замену только первых двух столбцовdf2:

x = df1['Item_ID'].values
y = df1['Item_Name'].values
cols = ['Item_slot_1', 'Item_slot_2']
z = df2[cols].values

m = np.arange(x.max() + 1, dtype=object)
m[x] = y

df2[cols] = m[z]

  Item_slot_1 Item_slot_2  Item_Slot_3
0           C           C            1
1           B           C            0
2           A           B            1

Этот тип индексации обеспечивает значительное увеличение производительности по сравнению с apply и replace:

import string

df1 = pd.DataFrame({'Item_ID': np.arange(26), 'Item_Name': list(string.ascii_uppercase)})
df2 = pd.DataFrame(np.random.randint(1, 26, (10000, 100)))

%%timeit
s = dict(zip(df1['Item_ID'], df1['Item_Name']))
df2.applymap(s.get)

158 ms ± 10.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
s = dict(zip(df1['Item_ID'], df1['Item_Name']))
df2.replace(s)

750 ms ± 34.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
s = dict(zip(df1['Item_ID'], df1['Item_Name']))
df2.apply(lambda x: x.map(s))

93.1 ms ± 4.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
x = df1['Item_ID'].values
y = df1['Item_Name'].values
z = df2.values
m = np.arange(x.max() + 1, dtype=object)
m[x] = y
pd.DataFrame(m[z], columns=df2.columns)

30.4 ms ± 182 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
0 голосов
/ 08 декабря 2018

Создайте словарь с помощью zip и передайте его applymap, или replace или apply с map:

s = dict(zip(df1['Item_ID'], df1['Item_Name']))
#if value not exist in df1['Item_ID'] get None in df2
df2 = df2.applymap(s.get)

Или:

#if value not exist in df1['Item_ID'] get original value in df2
df2 = df2.replace(s)

Или:

#if value not exist in df1['Item_ID'] get NaN in df2
df2 = df2.apply(lambda x: x.map(s))

print (df2)
  Item_slot_1 Item_slot_2 Item_Slot_3
0           C           C           B
1           B           C           A
2           A           B           B

РЕДАКТИРОВАТЬ:

Выможет указывать столбцы по именам для процесса:

cols = ['Item_slot_1','Item_slot_2','Item_Slot_3']

df2[cols] = df2[cols].applymap(s.get)
df2[cols] = df2[cols].replace(s)
df2[cols] = df2[cols].apply(lambda x: x.map(s))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...