2
votes

La recherche de correspondance entraîne une erreur - Ne peut comparer que des objets Series étiquetés de manière identique

J'ai ce qui suit:

Can only compare identically-labeled Series objects. 

Je veux ajouter une colonne à df1 qui renvoie la plage de df2. J'ai essayé comme suit:

Pour calculer df2 ['Range']:

def lookup_Range(Range):
    match = (df2['Min Q'].astype(float) <= df1['Quantity'].astype(float)) & (df2['Max Q'].astype(float) >= df1['Quantity'].astype(float)) & (df1['Combined'] == df2['Combined'])
    Range = df2['Range'][match]
    return Range.values[0]

df1['Quantity'].apply(lookup_Range)

Pour rechercher df1 ['Range']:

XXX

Mais j'obtiens l'erreur suivante:

df2['Range'] = df2['Min Q'].astype(float).astype(str) + ' - ' + df2['Max Q'].astype(float).astype(str)

Je ne suis pas sûr de ce que je fais mal. Les colonnes se répètent mais j'ai pensé que j'obtiendrais une correspondance unique dans chaque instance. Apprécier ton aide.


0 commentaires

3 Réponses :


0
votes

Tout d'abord, vous avez une erreur de type dans calcultaing df2 ['Range']. «Max Q» au lieu de «MaxQ». Deuxièmement, pouvez-vous clarifier quel est votre objectif final? J'ai essayé de commenter ici mais je n'ai pas assez de réputation. Je vais essayer de vous aider


2 commentaires

Oups, corrigé. La solution triée par recherche est très proche de ce que je veux faire, mais je veux aussi considérer où df1 ['Combiné'] = df2 ['Combiné']. Je ne sais pas comment ajouter cette condition supplémentaire.


Je vois, l'avez-vous résolu, il semble que le code proposé ci-dessus a fonctionné



3
votes

IIUC, vous avez besoin de:

bins = df2['Max Q'].tolist()
#[49, 99, 149, 199, 199, 299, 399, 499]
df1['bins']=pd.Series(np.searchsorted(bins, df1['Quantity'].values)).map(df2['Range'].to_dict())
print(df1)

  Combined  Quantity     bins
0        A         0     0-49
1        A        60    50-99
2        A        75    50-99
3        A       149  100-149
4        A       205    0-299
5        B       500      NaN
6        B       250    0-299
7        B       300  300-399
8        B       500      NaN


5 commentaires

C'est incroyablement utile. Que faire si j'ai également besoin de df1 ['Combined'] = df2 '[Combined'] avant d'appliquer les bins? En réalité, les bacs se chevaucheront, ils ne seront pas toujours ascendants. J'ai ajouté «C» aux colonnes «Combiné» dans mon exemple pour illustrer.


Je ne pense pas que cela fonctionne exactement. J'ai édité la première plage de «C» pour qu'elle soit 5-60 pour la rendre plus claire. Si j'ai df1 ['Combiné', 'Quantité'] = ['A', 5], je voudrais extraire la plage associée à 'A' donc 0-49. Mais si j'ai ['C', 45], je veux tirer la gamme 5-60. La plage dépend de df1 ['Combined'] = df2 '[Combined'] pour extraire la plage correcte. Comment puis-je ajouter cette condition?


semble que les bacs se chevauchent, donc groupby peut être nécessaire, incapable de le comprendre pour le moment. Publiera si je trouve quelque chose


exactement, je suis d'accord avec groupby, je pense que la fonction personnalisée devrait être bonne ici


@jezrael mais je ne peux rien trouver de bon. :( peut-être que vous pouvez poster une réponse. :) OP & moi a besoin d'aide. :)



2
votes

Utilisez merge d'abord avec filtrage par booléen indexation avec entre :

df = df.loc[df['Quantity'].between(df['Min Q'], df['Max Q']), ['Combined','Quantity','Range']]
print (df)
   Combined  Quantity      Range
0         A         0     0 - 49
5         A        60    50 - 99
9         A        75    50 - 99
14        A       149  100 - 149
25        B       250    0 - 299
30        B       300  300 - 399
36        C        40     5 - 60
39        C        45     5 - 60
43        C        75   50 - 100
46        C        80   50 - 100

Si vous voulez également filtrer uniquement certaines colonnes:

df2['Range'] = df2['Min Q'].astype(str) + ' - ' + df2['Max Q'].astype(str)

df = df1.merge(df2, on='Combined')
df = df[df['Quantity'].between(df['Min Q'], df['Max Q'])]
print (df)
   Combined  Quantity  Min Q  Max Q      Range
0         A         0      0     49     0 - 49
5         A        60     50     99    50 - 99
9         A        75     50     99    50 - 99
14        A       149    100    149  100 - 149
25        B       250      0    299    0 - 299
30        B       300    300    399  300 - 399
36        C        40      5     60     5 - 60
39        C        45      5     60     5 - 60
43        C        75     50    100   50 - 100
46        C        80     50    100   50 - 100


1 commentaires

intéressant, je n'ai pas pensé entre les deux. Nice @jezrael. Je vous remercie. :)