我来自SQL背景,是python的新手。一段时间以来,我一直在想如何解决这个特殊的问题,但什么都想不出来。
这是我的数据帧
from pandas import DataFrame
import numpy as np
Names1 = {'First_name': ['Jon','Bill','Billing','Maria','Martha','Emma']}
df = DataFrame(Names1,columns=['First_name'])
print(df)
names2 = {'name': ['Jo', 'Bi', 'Ma']}
df_2 = DataFrame(names2,columns=['name'])
print(df_2)
结果:
First_name
0 Jon
1 Bill
2 Billing
3 Maria
4 Martha
5 Emma
name
0 Jo
1 Bi
2 Ma
这段代码帮助我在df中识别哪个First_name以df_2中的元组开头
df['like_flg'] = np.where(df['First_name'].str.startswith(tuple(list(df_2['name']))), 'true', df['First_name'])
结果:
First_name like_flg
0 Jon true
1 Bill true
2 Billing true
3 Maria true
4 Martha true
5 Emma Emma
我希望数据帧的最终输出将like_flg设置为有条件比较First_name字段的元组的值。最终期望输出见下文:
First_name like_flg
0 Jon Jo
1 Bill Bi
2 Billing Bi
3 Maria Ma
4 Martha Ma
5 Emma Emma
以下是我迄今为止尝试过的
df['like_flg'] = np.where(df['First_name'].str.startswith(tuple(list(df_2['name']))), tuple(list(df_2['name'])), df['First_name'])
此错误的结果:
`ValueError: operands could not be broadcast together with shapes (6,) (3,) (6,)`
然而,我也尝试过对齐这两个数据帧,这对我试图实现的用例不起作用。
有没有一种方法可以有条件地对齐数据帧以填充以元组开头的列?
我相信我面临的问题是,我用作比较的元组或数据帧与我想将元组附加到的数据帧大小不同。请参阅上面的内容以获得所需的输出。
提前感谢大家!
如果起始字符串的长度不同,可以使用.str.extract
df['like_flag'] = df['First_name'].str.extract('^('+'|'.join(df_2.name)+')')
df['like_flag'] = df['like_flag'].fillna(df.First_name) # Fill non matches.
我将df_2
修改为
name
0 Jo
1 Bi
2 Mar
这导致:
First_name like_flag
0 Jon Jo
1 Bill Bi
2 Billing Bi
3 Maria Mar
4 Martha Mar
5 Emma Emma
您可以使用np.where,
df['like_flg'] = np.where(df.First_name.str[:2].isin(df_2.name), df.First_name.str[:2], df.First_name)
First_name like_flg
0 Jon Jo
1 Bill Bi
2 Billing Bi
3 Maria Ma
4 Martha Ma
5 Emma Emma
使用numpy
find
v=df.First_name.values.astype(str)
s=df_2.name.values.astype(str)
df_2.name.dot((np.char.find(v,s[:,None])==0))
array(['Jo', 'Bi', 'Bi', 'Ma', 'Ma', ''], dtype=object)
然后我们把它分配回
df['New']=df_2.name.dot((np.char.find(v,s[:,None])==0))
df.loc[df['New']=='','New']=df.First_name
df
First_name New
0 Jon Jo
1 Bill Bi
2 Billing Bi
3 Maria Ma
4 Martha Ma
5 Emma Emma