使用另一个数据帧中的值修改数据框

时间:2014-12-25 16:33:41

标签: python pandas

假设我有2个数据框,df_adf_b如下:

import pandas as pd

DF_A

df_a = pd.DataFrame({"Letters": ['E', 'H', 'O', 'N', 'M', 'K', 'T', 'X'],
                     "Greek":['epsilon', 'eta', 'omicron', 'nu', 'mu', 
                              'kappa', 'tau', 'chi']})

     Greek Letters
0  epsilon       E
1      eta       H
2  omicron       O
3       nu       N
4       mu       M
5    kappa       K
6      tau       T
7      chi       X

DF_B

df_b = pd.DataFrame({"Letters": ['Y', 'E', 'N', 'X', 'B']})
df_b["Greek"] = ""

  Letters Greek
0       Y      
1       E      
2       N      
3       X      
4       B      

我想使用df_b中的相应值填写df_a中的'Greek'列,我可以使用嵌套循环执行此操作,如下所示:

for i, row in df_a.iterrows():
    temp1 = row['Letters']
    for k, row in df_b.iterrows():
        temp2 = row['Letters']
        if temp1 == temp2:
            df_b.loc[k, "Greek"]=df_a.loc[i, "Greek"]

DF_B

Letters    Greek
0       Y         
1       E  epsilon
2       N       nu
3       X      chi
4       B     

首先,我想知道我是否可以使用mergezipjoin或其他连接函数更有效地实现相同的结果。其次,如果我在else语句中提供匹配的if,如下所示:

else: df_b.loc[k, "Greek"] = float('nan')

我预计这将用NaN填充空单元格而不修改其他单元格。相反,我得到类似的东西:

DF_B

  Letters Greek
0       Y   NaN
1       E   NaN
2       N   NaN
3       X   chi
4       B   NaN

感谢您对2分的看法。欢迎任何其他反馈。

1 个答案:

答案 0 :(得分:2)

最快的方法是设置' Letters'作为df_a的索引,然后调用map

In [11]:

df_a = df_a.set_index('Letters')
df_b['Greek'] = df_b['Letters'].map(df_a['Greek'])
df_b
Out[11]:
  Letters    Greek
0       Y      NaN
1       E  epsilon
2       N       nu
3       X      chi
4       B      NaN

只是为了展示你的循环中的缺陷,值得印出所发生的事情:

In [17]:

for i, row in df_a.iterrows():
    temp1 = row['Letters']
    for k, row in df_b.iterrows():
        temp2 = row['Letters']
        if temp1 == temp2:
            print("match i:", i, "k:", k, "letter:", temp2)
        else:
            print("no match i:", i, "k:", k, "letter:", temp2)
no match i: 0 k: 0 letter: Y
match i: 0 k: 1 letter: E
no match i: 0 k: 2 letter: N
no match i: 0 k: 3 letter: X
no match i: 0 k: 4 letter: B
no match i: 1 k: 0 letter: Y
no match i: 1 k: 1 letter: E
no match i: 1 k: 2 letter: N
no match i: 1 k: 3 letter: X
no match i: 1 k: 4 letter: B
no match i: 2 k: 0 letter: Y
no match i: 2 k: 1 letter: E
no match i: 2 k: 2 letter: N
no match i: 2 k: 3 letter: X
no match i: 2 k: 4 letter: B
no match i: 3 k: 0 letter: Y
no match i: 3 k: 1 letter: E
match i: 3 k: 2 letter: N
no match i: 3 k: 3 letter: X
no match i: 3 k: 4 letter: B
no match i: 4 k: 0 letter: Y
no match i: 4 k: 1 letter: E
no match i: 4 k: 2 letter: N
no match i: 4 k: 3 letter: X
no match i: 4 k: 4 letter: B
no match i: 5 k: 0 letter: Y
no match i: 5 k: 1 letter: E
no match i: 5 k: 2 letter: N
no match i: 5 k: 3 letter: X
no match i: 5 k: 4 letter: B
no match i: 6 k: 0 letter: Y
no match i: 6 k: 1 letter: E
no match i: 6 k: 2 letter: N
no match i: 6 k: 3 letter: X
no match i: 6 k: 4 letter: B
no match i: 7 k: 0 letter: Y
no match i: 7 k: 1 letter: E
no match i: 7 k: 2 letter: N
match i: 7 k: 3 letter: X
no match i: 7 k: 4 letter: B

因此,虽然您进行了初始匹配,但是再次循环遍历这些行并使用NaN进行闪烁,而不是跳过它们。

<强>计时

In [22]:

df_a = df_a.set_index('Letters')
%timeit df_b['Greek'] = df_b['Letters'].map(df_a['Greek'])

1000 loops, best of 3: 710 µs per loop
In [24]:

%%timeit 
for i, row in df_a.iterrows():
    temp1 = row['Letters']
    for k, row in df_b.iterrows():
        temp2 = row['Letters']
        if temp1 == temp2:
            df_b.loc[k, "Greek"]=df_a.loc[i, "Greek"]
100 loops, best of 3: 12.7 ms per loop

这里调用地图的速度快了近18倍,这是一个矢量化函数,并且可以更好地扩展。