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такие же, какItemTypeindataframe1. - некоторые
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'])
времени
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)
вы можете конвертировать 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'])

