Pandas:根据来自另一列的匹配替换列值

时间:2016-07-19 19:11:05

标签: python python-2.7 pandas dataframe

我在第一个数据框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中的某些ItemTypedataframe1相同 ItemType
  • dataframe2中的某些null具有ItemType值,例如yellowCabbage。
  • dataframe2中的
  • ItemTypedataframe
  • 中的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

下面给出的匹配替换不起作用。他们正在插入df1.loc[df1['ItemType'].isin(df2['ItemType'])]=df2[['NewType']] 值而不是实际值。这些是基于SO的讨论here

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

OR

egrep

提前致谢

修改
两个数据框中的两个列标题具有不同的名称。因此,dataframe1列是ItemType1,第二个数据帧中的第一列是ItemType2。错过了第一次编辑。

3 个答案:

答案 0 :(得分:5)

使用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

答案 1 :(得分:4)

您可以将::before(n)转换为由df2编制索引的系列,然后在'ItemType2'上使用replace

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

答案 2 :(得分:3)

此方法要求您将列名设置为“type”,然后可以使用merge和np.where

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

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