Pandas: заменить значения столбцов на основе совпадения из другого столбца

у меня есть столбец в первом фрейме данных df1["ItemType"] ниже

Dataframe1

ItemType1
redTomato
whitePotato
yellowPotato
greenCauliflower
yellowCauliflower
yelloSquash
redOnions
YellowOnions
WhiteOnions
yellowCabbage
GreenCabbage

мне нужно заменить это на основе словаря, созданного из другого фрейма данных.

Dataframe2

ItemType2          newType
whitePotato        Potato
yellowPotato       Potato
redTomato          Tomato
yellowCabbage   
GreenCabbage    
yellowCauliflower   yellowCauliflower
greenCauliflower    greenCauliflower
YellowOnions        Onions
WhiteOnions         Onions
yelloSquash         Squash
redOnions           Onions

заметил, что

  • на dataframe2 часть ItemType такие же, как ItemType in dataframe1.
  • некоторые ItemType в dataframe2 есть null ценности, как yellowCabbage.
  • ItemType в dataframe2 порядок в отношенииItemType на dataframe

мне нужно заменить значения в Dataframe1 ItemType столбец, если есть соответствие для значения в соответствующем Dataframe2 ItemType С newType имея в виду выше исключения, перечисленные в маркерных пунктах.
Если совпадения нет, то значения должны быть такими, как они есть [ без изменений].

пока у меня есть.

import pandas as pd

#read second `csv-file`
df2 = pd.read_csv('mappings.csv',names = ["ItemType", "newType"])
#conver to dict
df2=df2.set_index('ItemType').T.to_dict('list')

ниже дана замена на матч не работает. Они вставляют NaN значения вместо фактических. Они основаны на обсуждении здесь на SO.

df1.loc[df1['ItemType'].isin(df2['ItemType'])]=df2[['NewType']]

или

df1['ItemType']=df2['ItemType'].map(df2)

спасибо заранее

редактировать
Два заголовка столбцов в обоих фреймах данных имеют разные имена. Таким образом, столбец dataframe1 на ItemType1 и первый столбец во втором фрейме данных-ItemType2. Пропустил это при первом редактировании.

3 ответов


использовать map

вся логика вам нужно:

def update_type(t1, t2, dropna=False):
    return t1.map(t2).dropna() if dropna else t1.map(t2).fillna(t1)

давайте сделаем 'ItemType2' индекс Dataframe2

update_type(Dataframe1.ItemType1,
            Dataframe2.set_index('ItemType2').newType)

0                Tomato
1                Potato
2                Potato
3      greenCauliflower
4     yellowCauliflower
5                Squash
6                Onions
7                Onions
8                Onions
9         yellowCabbage
10         GreenCabbage
Name: ItemType1, dtype: object

update_type(Dataframe1.ItemType1,
            Dataframe2.set_index('ItemType2').newType,
            dropna=True)

0                Tomato
1                Potato
2                Potato
3      greenCauliflower
4     yellowCauliflower
5                Squash
6                Onions
7                Onions
8                Onions
Name: ItemType1, dtype: object

проверка

updated = update_type(Dataframe1.ItemType1, Dataframe2.set_index('ItemType2').newType)

pd.concat([Dataframe1, updated], axis=1, keys=['old', 'new'])

enter image description here


времени

def root(Dataframe1, Dataframe2):
    return Dataframe1['ItemType1'].replace(Dataframe2.set_index('ItemType2')['newType'].dropna())

def piRSquared(Dataframe1, Dataframe2):
    t1 = Dataframe1.ItemType1
    t2 = Dataframe2.set_index('ItemType2').newType
    return update_type(t1, t2)

enter image description here


вы можете конвертировать df2 в ряд, индексированный 'ItemType2', а затем использовать replace on df1:

# Make df2 a Series indexed by 'ItemType'.
df2 = df2.set_index('ItemType2')['newType'].dropna()

# Replace values in df1.
df1['ItemType1'] = df1['ItemType1'].replace(df2)

или в одной строке, если вы не хотите изменять df2:

df1['ItemType1'] = df1['ItemType1'].replace(df2.set_index('ItemType2')['newType'].dropna())

этот метод требует, чтобы вы установили имена столбцов в "тип", затем вы можете установить с помощью merge и np.где

df3 = df1.merge(df2,how='inner',on='type')['type','newType']

df3['newType'] = np.where(df['newType'].isnull(),df['type'],df['newType'])