1
votes

Aligner conditionnellement deux dataframes afin de dériver une colonne transmise comme condition dans numpy où

Je viens d'un background SQL et je suis nouveau en python. J'essaie de trouver 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

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

Résultats à ceci:

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

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

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

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 du dataframe soit définissez like_flg sur la valeur du tuple dans lequel le champ First_name est comparé conditionnellement. Voir ci-dessous pour la sortie finale souhaitée:

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

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

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

entraîne cette erreur:

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)

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

Existe-t-il un moyen d'aligner conditionnellement les dataframes pour remplir les colonnes commençant par le tuple?

Je pense que le problème auquel je suis confronté est que le tuple ou le dataframe que j'utilise comme comparaison n'est pas de la même taille que le dataframe auquel je veux ajouter le tuple. Veuillez voir ci-dessus pour le résultat souhaité.

Merci à tous d'avance!


1 commentaires

df_2 est-il toujours seulement 2 caractères, ou peut-il être plus / moins?


3 Réponses :


2
votes

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


3 commentaires

trouver un alt :-)


ah, donc celui-ci compare essentiellement une sous-chaîne de la colonne First_name. J'ai accepté la réponse @ALollz car elle est plus flexible, merci pour la réponse!


@ noypikobe24 s'ils sont tous 2 caractères bien que je pense que cette solution est plus appropriée et probablement beaucoup plus rapide.



3
votes

Si vos chaînes de départ diffèrent en longueur, vous pouvez utiliser .str.extract

  First_name like_flag
0        Jon        Jo
1       Bill        Bi
2    Billing        Bi
3      Maria       Mar
4     Martha       Mar
5       Emma      Emma

J'ai modifié df_2 en être

  name
0   Jo
1   Bi
2  Mar

qui mène à:

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.


1 commentaires

Ce joli :-)



1
votes

Faites avec numpy find

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

Ensuite, nous le réattribuons

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)


0 commentaires