有条件地对齐两个数据帧,以派生作为传入numpy中的条件的列,其中

时间:2019-01-26 22:12:33

标签: python pandas numpy numpy-broadcasting

我来自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,)` 

我也尝试过对齐两个数据框,但是,这不适用于我要实现的用例。

是否可以有条件地对齐数据框以填充以元组开头的列?

我认为我所面临的问题是,我用作比较的元组或数据框的大小与我要向其附加元组的数据框的大小不同。请参阅上面的所需输出。

谢谢大家前进!

3 个答案:

答案 0 :(得分:3)

如果起始字符串的长度不同,则可以使用.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

答案 1 :(得分:2)

您可以在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

答案 2 :(得分:1)

使用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