Pandas:根据字符串的一部分是否在另一列中的任意位置创建新列
Pandas: Creating a new column based on if part of a string is anywhere in another column
假设我们有两个数据帧:
df1 = pd.DataFrame({
0: 'ETERNITON',
1: 'CIELOON',
2: 'M.DIASBRANCOON',
3: 'IRBBRASIL REON',
4: '01/00 ATACADÃO S.A ON',
5: 'AMBEV S/A ON',
6: '01/00 RUMO S.A. ON',
7: 'COGNA ONON',
8: 'CURY S/A'}.items(), columns=['index', 'name']).set_index('index')
df2 = pd.DataFrame({'name': {0: 'ALLIARON', 1: 'M.DIASBRANCOON', 2: 'AMBEVS/AON', 3: 'CIELOON',
4: 'AESBRASILON', 5: 'BRASILAGROON', 6: 'IRBBRASILREON', 7: 'ATACADÃOS.AON', 8: 'ALPARGATASON',
9: 'RUMOS.A.ON', 10: 'COGNAONON'},
'yf_ticker': {0: 'AALR3.SA', 1: 'MDIA3.SA', 2: 'ABEV3.SA', 3: 'CIEL3.SA', 4: 'AESB3.SA',
5: 'AGRO3.SA', 6: 'IRBR3.SA', 7: 'CRFB3.SA', 8: 'ALPA3.SA', 9: 'RAIL3.SA', 10: 'COGN3.SA'}})
我想使用 df2 中的 'yf_ticker' 列在 df1 中创建一个新列 ('ticker')。如果 df2['yf_ticker']
中的 name/string 在 df1['name']
中(即使它不是完全匹配),则将 df2 中的 yf_ticker 添加到 df1['ticker']
中的该行.为了清楚起见,预期的输出将类似于:
print(df1)
name ticker
ETERNITON Missing or N/A or Nan
CIELOON CIEL3.SA
M.DIASBRANCOON MDIA3.SA
IRBBRASIL REON IRBR3.SA
01/00 ATACADÃO S.A ON CRFB3.SA
AMBEV S/A ON ABEV3.SA
01/00 RUMO S.A. ON RAIL3.SA
COGNA ONON COGN3.SA
CURY S/A Missing or N/A or Nan
我尝试的解决方案:
df1['name'] = df1['name'].str.replace(" ","")
for i in range(len(df1)):
for j in range(len(df2)):
if df2.iloc[j,0] in df1.iloc[i,0]:
df1.loc[i, 'ticker'] = df2.iloc[j,1]
虽然它有效,但在我看来,对于更大的数据集,这样的 for 循环是低效的。有没有更快(或'vectorized')的方法来做到这一点?
我建议对 name
列进行模糊匹配,然后从匹配行中获取 yf_ticker
。这是 python 的内置 difflib
:
的示例
import difflib
df1['yf_ticker'] = df1['name'].apply(lambda x: df2.loc[df2['name'] == y[0], 'yf_ticker'].iloc[0] if (y := (difflib.get_close_matches(x, df2.name))) else None)
输出:
index
name
yf_ticker
0
ETERNITON
1
CIELOON
CIEL3.SA
2
M.DIASBRANCOON
MDIA3.SA
3
IRBBRASIL REON
IRBR3.SA
4
01/00 ATACADÃO S.A ON
CRFB3.SA
5
AMBEV S/A ON
ABEV3.SA
6
01/00 RUMO S.A. ON
RAIL3.SA
7
COGNA ONON
COGN3.SA
8
CURY S/A
假设我们有两个数据帧:
df1 = pd.DataFrame({
0: 'ETERNITON',
1: 'CIELOON',
2: 'M.DIASBRANCOON',
3: 'IRBBRASIL REON',
4: '01/00 ATACADÃO S.A ON',
5: 'AMBEV S/A ON',
6: '01/00 RUMO S.A. ON',
7: 'COGNA ONON',
8: 'CURY S/A'}.items(), columns=['index', 'name']).set_index('index')
df2 = pd.DataFrame({'name': {0: 'ALLIARON', 1: 'M.DIASBRANCOON', 2: 'AMBEVS/AON', 3: 'CIELOON',
4: 'AESBRASILON', 5: 'BRASILAGROON', 6: 'IRBBRASILREON', 7: 'ATACADÃOS.AON', 8: 'ALPARGATASON',
9: 'RUMOS.A.ON', 10: 'COGNAONON'},
'yf_ticker': {0: 'AALR3.SA', 1: 'MDIA3.SA', 2: 'ABEV3.SA', 3: 'CIEL3.SA', 4: 'AESB3.SA',
5: 'AGRO3.SA', 6: 'IRBR3.SA', 7: 'CRFB3.SA', 8: 'ALPA3.SA', 9: 'RAIL3.SA', 10: 'COGN3.SA'}})
我想使用 df2 中的 'yf_ticker' 列在 df1 中创建一个新列 ('ticker')。如果 df2['yf_ticker']
中的 name/string 在 df1['name']
中(即使它不是完全匹配),则将 df2 中的 yf_ticker 添加到 df1['ticker']
中的该行.为了清楚起见,预期的输出将类似于:
print(df1)
name ticker
ETERNITON Missing or N/A or Nan
CIELOON CIEL3.SA
M.DIASBRANCOON MDIA3.SA
IRBBRASIL REON IRBR3.SA
01/00 ATACADÃO S.A ON CRFB3.SA
AMBEV S/A ON ABEV3.SA
01/00 RUMO S.A. ON RAIL3.SA
COGNA ONON COGN3.SA
CURY S/A Missing or N/A or Nan
我尝试的解决方案:
df1['name'] = df1['name'].str.replace(" ","")
for i in range(len(df1)):
for j in range(len(df2)):
if df2.iloc[j,0] in df1.iloc[i,0]:
df1.loc[i, 'ticker'] = df2.iloc[j,1]
虽然它有效,但在我看来,对于更大的数据集,这样的 for 循环是低效的。有没有更快(或'vectorized')的方法来做到这一点?
我建议对 name
列进行模糊匹配,然后从匹配行中获取 yf_ticker
。这是 python 的内置 difflib
:
import difflib
df1['yf_ticker'] = df1['name'].apply(lambda x: df2.loc[df2['name'] == y[0], 'yf_ticker'].iloc[0] if (y := (difflib.get_close_matches(x, df2.name))) else None)
输出:
index | name | yf_ticker |
---|---|---|
0 | ETERNITON | |
1 | CIELOON | CIEL3.SA |
2 | M.DIASBRANCOON | MDIA3.SA |
3 | IRBBRASIL REON | IRBR3.SA |
4 | 01/00 ATACADÃO S.A ON | CRFB3.SA |
5 | AMBEV S/A ON | ABEV3.SA |
6 | 01/00 RUMO S.A. ON | RAIL3.SA |
7 | COGNA ONON | COGN3.SA |
8 | CURY S/A |