Je viens d'un arrière-plan SQL et nouveau pour python. J'essaie de comprendre comment résoudre ce problème particulier depuis un certain temps maintenant et je suis incapable de trouver quoi que ce soit.

Voici mes dataframes

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)

Résultats à ceci:

   First_name
0        Jon
1       Bill
2    Billing
3      Maria
4     Martha
5       Emma
  name
0   Jo
1   Bi
2   Ma

Ce code m'aide à identifier dans df quel First_name commence par un tuple de df_2

df['like_flg'] = np.where(df['First_name'].str.startswith(tuple(list(df_2['name']))), 'true', df['First_name'])

Résultats à ceci:

First_name  like_flg
0   Jon     true
1   Bill    true
2   Billing true
3   Maria   true
4   Martha  true
5   Emma    Emma

Je voudrais que la sortie finale de la trame de données définisse le like_flg à la valeur du tuple dans lequel le champ First_name est comparé conditionnellement. Voir ci-dessous pour la sortie finale souhaitée:

First_name  like_flg
0   Jon     Jo
1   Bill    Bi
2   Billing Bi
3   Maria   Ma
4   Martha  Ma
5   Emma    Emma

Voici ce que j'ai essayé jusqu'à présent

df['like_flg'] = np.where(df['First_name'].str.startswith(tuple(list(df_2['name']))), tuple(list(df_2['name'])), df['First_name'])

Résulte de cette erreur:

`ValueError: operands could not be broadcast together with shapes (6,) (3,) (6,)` 

J'ai également essayé d'aligner les deux cadres de données, cependant, cela ne fonctionnera pas pour le cas d'utilisation que j'essaie de réaliser.

Existe-t-il un moyen d'aligner conditionnellement les cadres de données pour remplir les colonnes commençant par le tuple?

Je crois que le problème auquel je suis confronté est que le tuple ou la trame de données que j'utilise comme comparaison n'est pas de la même taille que la trame de données à laquelle je veux ajouter le tuple. Veuillez voir ci-dessus pour la sortie souhaitée.

Merci à tous d'avance!

1
noypikobe24 27 janv. 2019 à 01:12

3 réponses

Meilleure réponse

Si vos chaînes de départ diffèrent en longueur, vous pouvez utiliser .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.

J'ai modifié df_2 pour être

  name
0   Jo
1   Bi
2  Mar

Qui conduit à:

  First_name like_flag
0        Jon        Jo
1       Bill        Bi
2    Billing        Bi
3      Maria       Mar
4     Martha       Mar
5       Emma      Emma
3
ALollz 26 janv. 2019 à 22:29

À faire avec 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)

Ensuite, nous l'attribuons simplement

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
1
YO and BEN_W 27 janv. 2019 à 01:02

Vous pouvez utiliser 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
Vaishali 26 janv. 2019 à 22:19