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
indataframe1
. - некоторые
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'])