假设我有2个数据框,df_a
和df_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
首先,我想知道我是否可以使用merge
,zip
,join
或其他连接函数更有效地实现相同的结果。其次,如果我在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分的看法。欢迎任何其他反馈。
答案 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倍,这是一个矢量化函数,并且可以更好地扩展。