根据另一个数据框替换一个数据框中的Value

时间:2019-05-05 08:35:23

标签: python-3.x pandas

我有2个数据框:

>>> tab2
Old_name             New_name
Genus_1_sp1_A     Genus_1_sp1
Genus_2_sp1_A     Genus_2_sp1
Genus_3_sp1_A     Genus_3_sp1
Genus_4_sp1_A     Genus_4_sp1

并且想法是解析另一个数据帧,例如:

Sp_name

并在与New_name中的tab2匹配的tab1中替换Sp_name,然后用相应的Old_name替换>>> tab1 Value Sp_name 0 None ROOT 1 0.066 Genus_1_sp1_A 2 0.1044 Genus_2_sp1_A 3 0.0708 EDGE 4 0.0586 Genus_3_sp1_A 5 0.0083 Genus_4_sp1_A 例如,我应该得到:

for i in tab1['Sp_name']:
    found= tab2[tab2['New_name'].str.contains(i)]
    if len(found) > 0:
        tab1.at[i,'Sp_name'] = str(row['Old_name'])

我到目前为止尝试过:

<div ng-app='someApp'>
  <div ng-controller="SomeCtrl as ctrl">
<hot-table settings="tableSettings" datarows="items">
    <hot-column data="id" title="'ID'"></hot-column>
    <hot-column data="name.first" title="'First Name'" type="grayedOut" read-only></hot-column>
    <hot-column data="name.last" title="'Last Name'" type="grayedOut" read-only></hot-column>
    <hot-column data="address" title="'Address'" width="150"></hot-column>
    <hot-column data="price" title="'Price'" type="'numeric'" width="80" format="'$ 0,0.00'"></hot-column>
    <hot-column data="date" title="'Date'" width="150" date-format="'YYYY-MM-DD'" correct-format type="'date'"></hot-column>

    <hot-column data="isActive" title="'Is active'" type="'checkbox'" width="65" checked-template="'Yes'" unchecked-template="'No'"></hot-column>
</hot-table>

<input type="text" ng-change="search(query)" ng-model="query">

</div>
</div>

4 个答案:

答案 0 :(得分:2)

tab2创建一个名称词典,然后使用.replace将其替换回tab1

name_dict = dict(zip(tab2.New_name, tab2.Old_name))
tab1['Sp_name'] = tab1['Sp_name'].replace(name_dict)

tab1

    Value        Sp_name
0    None           ROOT
1   0.066  Genus_1_sp1_A
2  0.1044  Genus_2_sp1_A
3  0.0708           EDGE
4  0.0586  Genus_3_sp1_A
5  0.0083  Genus_4_sp1_A

答案 1 :(得分:1)

使用pd.merge

df['Sp_name'] = pd.merge(df1,df2.rename(columns={'New_name':'Sp_name'}),how='left' ,on='Sp_name').apply(lambda x: x['Old_name'] if x['Old_name'] == np.nan else x['Sp_name'], axis=1)

输出

    Value      Sp_name
0    None         ROOT
1   0.066  Genus_1_sp1
2  0.1044  Genus_2_sp1
3  0.0708         EDGE
4  0.0586  Genus_3_sp1
5  0.0083  Genus_4_sp1

答案 2 :(得分:1)

尝试DataFrame.update。它是为此要求而设计的。使用来自另一个DataFrame的非NA值进行修改。

这是我的示例代码供您参考:

from io import StringIO
import pandas as pd
from pprint import pprint

tab1="""
Value,Sp_name
None,ROOT
0.066,Genus_1_sp1
0.1044,Genus_2_sp1
0.0708,EDGE
0.0586,Genus_3_sp1
0.0083,Genus_4_sp1
"""
tab2="""
Old_name,New_name
Genus_1_sp1_A,Genus_1_sp1
Genus_2_sp1_A,Genus_2_sp1
Genus_3_sp1_A,Genus_3_sp1
Genus_4_sp1_A,Genus_4_sp1A
"""
df1 = pd.read_csv(StringIO(tab1)).set_index("Sp_name",drop=False)

df2=  pd.read_csv(StringIO(tab2)).rename(columns={"Old_name":"Sp_name"}).set_index("New_name")
df1.index.name ='New_name'

new_df = df1.copy()
new_df.update(df2)

print("\nthis is table 1 ")
pprint(df1,)

print("\nthis is table 2 ")

pprint(df2,)

print("\nthis is updated table")

pprint(new_df.reset_index(drop=True),)

这是输出。

this is table 1 
              Value      Sp_name
New_name                        
ROOT           None         ROOT
Genus_1_sp1   0.066  Genus_1_sp1
Genus_2_sp1  0.1044  Genus_2_sp1
EDGE         0.0708         EDGE
Genus_3_sp1  0.0586  Genus_3_sp1
Genus_4_sp1  0.0083  Genus_4_sp1

this is table 2 
                    Sp_name
New_name                   
Genus_1_sp1   Genus_1_sp1_A
Genus_2_sp1   Genus_2_sp1_A
Genus_3_sp1   Genus_3_sp1_A
Genus_4_sp1A  Genus_4_sp1_A

this is updated table
    Value        Sp_name
0    None           ROOT
1   0.066  Genus_1_sp1_A
2  0.1044  Genus_2_sp1_A
3  0.0708           EDGE
4  0.0586  Genus_3_sp1_A
5  0.0083    Genus_4_sp1

答案 3 :(得分:1)

您可以使用series.map()进行映射。它也是矢量化程度最高的(IMO):

tab1.Sp_name=tab1.Sp_name.map(tab2.set_index('New_name')['Old_name']).fillna(tab1.Sp_name)
print(tab1)

    Value        Sp_name
0    None           ROOT
1   0.066  Genus_1_sp1_A
2  0.1044  Genus_2_sp1_A
3  0.0708           EDGE
4  0.0586  Genus_3_sp1_A
5  0.0083  Genus_4_sp1_A